diff --git a/frontends/blif/blifparse.cc b/frontends/blif/blifparse.cc index 0aa3a173d..bff347ea2 100644 --- a/frontends/blif/blifparse.cc +++ b/frontends/blif/blifparse.cc @@ -245,7 +245,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool if (undef_wire != nullptr) module->rename(undef_wire, stringf("$undef$%d", ++blif_maxnum)); - autoidx = std::max(autoidx, blif_maxnum+1); + autoidx.ensure_at_least(blif_maxnum+1); blif_maxnum = 0; } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index dc851c019..9477b04a8 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -98,7 +98,7 @@ int RTLIL::IdString::really_insert(std::string_view p, std::unordered_map(StaticId::STATIC_ID_END)) return; auto it = global_refcount_storage_.find(idx); @@ -610,6 +614,8 @@ private: void put_reference() { + log_assert(!Multithreading::active()); + // put_reference() may be called from destructors after the destructor of // global_refcount_storage_ has been run. in this case we simply do nothing. if (index_ < static_cast(StaticId::STATIC_ID_END) || !destruct_guard_ok) diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 009da56b9..2c9b8304d 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -19,6 +19,7 @@ #include "kernel/yosys.h" #include "kernel/celltypes.h" +#include "kernel/log.h" #ifdef YOSYS_ENABLE_READLINE # include @@ -80,7 +81,7 @@ extern "C" PyObject* PyInit_pyosys(); YOSYS_NAMESPACE_BEGIN -int autoidx = 1; +Autoidx autoidx(1); int yosys_xtrace = 0; bool yosys_write_versions = true; const char* yosys_maybe_version() { @@ -108,9 +109,30 @@ uint32_t Hasher::fudge = 0; std::string yosys_share_dirname; std::string yosys_abc_executable; +bool Multithreading::active_ = false; + void init_share_dirname(); void init_abc_executable_name(); +Multithreading::Multithreading() { + log_assert(!active_); + active_ = true; +} + +Multithreading::~Multithreading() { + log_assert(active_); + active_ = false; +} + +void Autoidx::ensure_at_least(int v) { + value = std::max(value, v); +} + +int Autoidx::operator++(int) { + log_assert(!Multithreading::active()); + return value++; +} + void memhasher_on() { #if defined(__linux__) || defined(__FreeBSD__) diff --git a/kernel/yosys_common.h b/kernel/yosys_common.h index 2374182ee..55e7b71eb 100644 --- a/kernel/yosys_common.h +++ b/kernel/yosys_common.h @@ -267,7 +267,30 @@ int ceil_log2(int x) YS_ATTRIBUTE(const); template int GetSize(const T &obj) { return obj.size(); } inline int GetSize(RTLIL::Wire *wire); -extern int autoidx; +// When multiple threads are accessing RTLIL, one of these guard objects +// must exist. +struct Multithreading +{ + Multithreading(); + ~Multithreading(); + // Returns true when multiple threads are accessing RTLIL. + // autoidx cannot be used during such times. + // IdStrings cannot be created during such times. + static bool active() { return active_; } +private: + static bool active_; +}; + +struct Autoidx { + Autoidx(int value) : value(value) {} + operator int() const { return value; } + void ensure_at_least(int v); + int operator++(int); +private: + int value; +}; + +extern Autoidx autoidx; extern int yosys_xtrace; extern bool yosys_write_versions;