diff --git a/include/verilated.cpp b/include/verilated.cpp index 23c51b7eb..215a5f137 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -202,7 +202,7 @@ IData VL_RAND32() VL_MT_SAFE { t_seeded = true; long seedval; { - VerilatedLockGuard guard(s_mutex); + VerilatedLockGuard lock(s_mutex); seedval = lrand48()<<16 ^ lrand48(); if (!seedval) seedval++; } @@ -1612,7 +1612,7 @@ Verilated::ThreadLocal::~ThreadLocal() { } void Verilated::debug(int val) VL_MT_SAFE { - VerilatedLockGuard guard(m_mutex); + VerilatedLockGuard lock(m_mutex); s_s.s_debug = val; if (val) { #ifdef VL_DEBUG @@ -1623,23 +1623,23 @@ void Verilated::debug(int val) VL_MT_SAFE { } } void Verilated::randReset(int val) VL_MT_SAFE { - VerilatedLockGuard guard(m_mutex); + VerilatedLockGuard lock(m_mutex); s_s.s_randReset = val; } void Verilated::calcUnusedSigs(bool flag) VL_MT_SAFE { - VerilatedLockGuard guard(m_mutex); + VerilatedLockGuard lock(m_mutex); s_s.s_calcUnusedSigs = flag; } void Verilated::gotFinish(bool flag) VL_MT_SAFE { - VerilatedLockGuard guard(m_mutex); + VerilatedLockGuard lock(m_mutex); s_s.s_gotFinish = flag; } void Verilated::assertOn(bool flag) VL_MT_SAFE { - VerilatedLockGuard guard(m_mutex); + VerilatedLockGuard lock(m_mutex); s_s.s_assertOn = flag; } void Verilated::fatalOnVpiError(bool flag) VL_MT_SAFE { - VerilatedLockGuard guard(m_mutex); + VerilatedLockGuard lock(m_mutex); s_s.s_fatalOnVpiError = flag; } @@ -1661,7 +1661,7 @@ const char* Verilated::catName(const char* n1, const char* n2) VL_MT_SAFE { } void Verilated::flushCb(VerilatedVoidCb cb) VL_MT_SAFE { - VerilatedLockGuard guard(m_mutex); + VerilatedLockGuard lock(m_mutex); if (s_flushCb == cb) {} // Ok - don't duplicate else if (!s_flushCb) { s_flushCb=cb; } else { @@ -1671,14 +1671,14 @@ void Verilated::flushCb(VerilatedVoidCb cb) VL_MT_SAFE { } void Verilated::flushCall() VL_MT_SAFE { - VerilatedLockGuard guard(m_mutex); + VerilatedLockGuard lock(m_mutex); if (s_flushCb) (*s_flushCb)(); fflush(stderr); fflush(stdout); } void Verilated::commandArgs(int argc, const char** argv) VL_MT_SAFE { - VerilatedLockGuard guard(m_mutex); + VerilatedLockGuard lock(m_mutex); s_args.argc = argc; s_args.argv = argv; VerilatedImp::commandArgs(argc,argv); @@ -1716,16 +1716,6 @@ void Verilated::scopesDump() VL_MT_SAFE { VerilatedImp::scopesDump(); } -void Verilated::numThreads(unsigned threads) VL_MT_SAFE { - VerilatedImp::numThreads(threads); -} -unsigned Verilated::numThreads() VL_MT_SAFE { - return VerilatedImp::numThreads(); -} -void Verilated::spawnThreads() VL_MT_SAFE { - VerilatedImp::spawnThreads(); -} - const VerilatedScope* Verilated::scopeFind(const char* namep) VL_MT_SAFE { return VerilatedImp::scopeFind(namep); } @@ -1948,7 +1938,7 @@ void VerilatedScope::scopeDump() const { //=========================================================================== // VerilatedOneThreaded:: Methods -#ifdef VL_THREADED +#if defined(VL_THREADED) && defined(VL_DEBUG) void VerilatedAssertOneThread::fatal_different() VL_MT_SAFE { VL_FATAL_MT(__FILE__, __LINE__, "", "Routine called that is single threaded, but called from" " a different thread then the expected constructing thread"); diff --git a/include/verilated.h b/include/verilated.h index e47b6ee14..49b270a99 100644 --- a/include/verilated.h +++ b/include/verilated.h @@ -437,17 +437,6 @@ public: /// releases - contact the authors before production use. static void scopesDump() VL_MT_SAFE; - /// Set the number of threads to execute on. - /// 0x0 = use all available CPU threads, or 1 if no support compiled in - /// Ignored after spawnThreads() has been called - static void numThreads(unsigned threads) VL_MT_SAFE; - static unsigned numThreads() VL_MT_SAFE; - /// Spawn child threads, using numThreads() as # of threads - /// Verilator calls this automatically on the first eval() call - /// User code may call it earlier if desired - /// Once called the first time, later calls are ignored - static void spawnThreads() VL_MT_SAFE; - public: // METHODS - INTERNAL USE ONLY (but public due to what uses it) // Internal: Create a new module name by concatenating two strings diff --git a/include/verilated_cov.cpp b/include/verilated_cov.cpp index c5d19e6ea..620a45a8d 100644 --- a/include/verilated_cov.cpp +++ b/include/verilated_cov.cpp @@ -233,12 +233,12 @@ public: // PUBLIC METHODS void clear() VL_EXCLUDES(m_mutex) { Verilated::quiesce(); - VerilatedLockGuard guard(m_mutex); + VerilatedLockGuard lock(m_mutex); clearGuts(); } void clearNonMatch(const char* matchp) VL_EXCLUDES(m_mutex) { Verilated::quiesce(); - VerilatedLockGuard guard(m_mutex); + VerilatedLockGuard lock(m_mutex); if (matchp && matchp[0]) { ItemList newlist; for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) { @@ -254,7 +254,7 @@ public: } void zero() VL_EXCLUDES(m_mutex) { Verilated::quiesce(); - VerilatedLockGuard guard(m_mutex); + VerilatedLockGuard lock(m_mutex); for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) { (*it)->zero(); } @@ -262,18 +262,18 @@ public: // We assume there's always call to i/f/p in that order void inserti (VerilatedCovImpItem* itemp) VL_EXCLUDES(m_mutex) { - VerilatedLockGuard guard(m_mutex); + VerilatedLockGuard lock(m_mutex); assert(!m_insertp); m_insertp = itemp; } void insertf (const char* filenamep, int lineno) VL_EXCLUDES(m_mutex) { - VerilatedLockGuard guard(m_mutex); + VerilatedLockGuard lock(m_mutex); m_insertFilenamep = filenamep; m_insertLineno = lineno; } void insertp (const char* ckeyps[MAX_KEYS], const char* valps[MAX_KEYS]) VL_EXCLUDES(m_mutex) { - VerilatedLockGuard guard(m_mutex); + VerilatedLockGuard lock(m_mutex); assert(m_insertp); // First two key/vals are filename ckeyps[0]="filename"; valps[0]=m_insertFilenamep; @@ -328,7 +328,7 @@ public: void write(const char* filename) VL_EXCLUDES(m_mutex) { Verilated::quiesce(); - VerilatedLockGuard guard(m_mutex); + VerilatedLockGuard lock(m_mutex); #ifndef VM_COVERAGE VL_FATAL_MT("",0,"","%Error: Called VerilatedCov::write when VM_COVERAGE disabled\n"); #endif diff --git a/include/verilated_imp.h b/include/verilated_imp.h index fa5eac60b..621eef154 100644 --- a/include/verilated_imp.h +++ b/include/verilated_imp.h @@ -94,7 +94,7 @@ public: // METHODS //// Add message to queue (called by producer) void post(const VerilatedMsg& msg) VL_EXCLUDES(m_mutex) { - VerilatedLockGuard guard(m_mutex); + VerilatedLockGuard lock(m_mutex); m_queue.insert(msg); // Pass by value to copy the message into queue ++m_depth; } @@ -199,15 +199,10 @@ class VerilatedImp { std::vector m_fdps VL_GUARDED_BY(m_fdMutex); ///< File descriptors std::deque m_fdFree VL_GUARDED_BY(m_fdMutex); ///< List of free descriptors (SLOW - FOPEN/CLOSE only) - // Threads - VerilatedMutex m_threadMutex; ///< Protect m_numThreads, etc - bool m_spawned VL_GUARDED_BY(m_threadMutex); ///< Already called spawnThreads() - unsigned m_numThreads VL_GUARDED_BY(m_threadMutex); ///< Number of threads user requested, 0x0=all cpus - public: // But only for verilated*.cpp // CONSTRUCTORS VerilatedImp() - : m_argVecLoaded(false), m_exportNext(0), m_spawned(false), m_numThreads(0) { + : m_argVecLoaded(false), m_exportNext(0) { m_fdps.resize(3); m_fdps[0] = stdin; m_fdps[1] = stdout; @@ -218,7 +213,7 @@ private: VL_UNCOPYABLE(VerilatedImp); public: static void internalsDump() VL_MT_SAFE { - VerilatedLockGuard guard(s_s.m_argMutex); + VerilatedLockGuard lock(s_s.m_argMutex); VL_PRINTF_MT("internalsDump:\n"); VL_PRINTF_MT(" Argv:"); for (ArgVec::const_iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) { @@ -234,16 +229,16 @@ public: // METHODS - arguments public: static void commandArgs(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex) { - VerilatedLockGuard guard(s_s.m_argMutex); + VerilatedLockGuard lock(s_s.m_argMutex); s_s.m_argVec.clear(); // Always clear commandArgsAddGuts(argc, argv); } static void commandArgsAdd(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex) { - VerilatedLockGuard guard(s_s.m_argMutex); + VerilatedLockGuard lock(s_s.m_argMutex); commandArgsAddGuts(argc, argv); } static std::string argPlusMatch(const char* prefixp) VL_EXCLUDES(s_s.m_argMutex) { - VerilatedLockGuard guard(s_s.m_argMutex); + VerilatedLockGuard lock(s_s.m_argMutex); // Note prefixp does not include the leading "+" size_t len = strlen(prefixp); if (VL_UNLIKELY(!s_s.m_argVecLoaded)) { @@ -272,14 +267,14 @@ public: // There's often many more scopes than userdata's and thus having a ~48byte // per map overhead * N scopes would take much more space and cache thrashing. static inline void userInsert(const void* scopep, void* userKey, void* userData) VL_MT_SAFE { - VerilatedLockGuard guard(s_s.m_userMapMutex); + VerilatedLockGuard lock(s_s.m_userMapMutex); UserMap::iterator it=s_s.m_userMap.find(std::make_pair(scopep,userKey)); if (it != s_s.m_userMap.end()) it->second = userData; // When we support VL_THREADs, we need a lock around this insert, as it's runtime else s_s.m_userMap.insert(it, std::make_pair(std::make_pair(scopep,userKey),userData)); } static inline void* userFind(const void* scopep, void* userKey) VL_MT_SAFE { - VerilatedLockGuard guard(s_s.m_userMapMutex); + VerilatedLockGuard lock(s_s.m_userMapMutex); UserMap::const_iterator it=s_s.m_userMap.find(std::make_pair(scopep,userKey)); if (VL_LIKELY(it != s_s.m_userMap.end())) return it->second; else return NULL; @@ -288,7 +283,7 @@ private: /// Symbol table destruction cleans up the entries for each scope. static void userEraseScope(const VerilatedScope* scopep) VL_MT_SAFE { // Slow ok - called once/scope on destruction, so we simply iterate. - VerilatedLockGuard guard(s_s.m_userMapMutex); + VerilatedLockGuard lock(s_s.m_userMapMutex); for (UserMap::iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ) { if (it->first.first == scopep) { s_s.m_userMap.erase(it++); @@ -298,7 +293,7 @@ private: } } static void userDump() VL_MT_SAFE { - VerilatedLockGuard guard(s_s.m_userMapMutex); // Avoid it changing in middle of dump + VerilatedLockGuard lock(s_s.m_userMapMutex); // Avoid it changing in middle of dump bool first = true; for (UserMap::const_iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ++it) { if (first) { VL_PRINTF_MT(" userDump:\n"); first=false; } @@ -311,27 +306,27 @@ public: // But only for verilated*.cpp // METHODS - scope name static void scopeInsert(const VerilatedScope* scopep) VL_MT_SAFE { // Slow ok - called once/scope at construction - VerilatedLockGuard guard(s_s.m_nameMutex); + VerilatedLockGuard lock(s_s.m_nameMutex); VerilatedScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name()); if (it == s_s.m_nameMap.end()) { s_s.m_nameMap.insert(it, std::make_pair(scopep->name(),scopep)); } } static inline const VerilatedScope* scopeFind(const char* namep) VL_MT_SAFE { - VerilatedLockGuard guard(s_s.m_nameMutex); // If too slow, can assume this is only VL_MT_SAFE_POSINIT + VerilatedLockGuard lock(s_s.m_nameMutex); // If too slow, can assume this is only VL_MT_SAFE_POSINIT VerilatedScopeNameMap::const_iterator it=s_s.m_nameMap.find(namep); if (VL_LIKELY(it != s_s.m_nameMap.end())) return it->second; else return NULL; } static void scopeErase(const VerilatedScope* scopep) VL_MT_SAFE { // Slow ok - called once/scope at destruction - VerilatedLockGuard guard(s_s.m_nameMutex); + VerilatedLockGuard lock(s_s.m_nameMutex); userEraseScope(scopep); VerilatedScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name()); if (it != s_s.m_nameMap.end()) s_s.m_nameMap.erase(it); } static void scopesDump() VL_MT_SAFE { - VerilatedLockGuard guard(s_s.m_nameMutex); + VerilatedLockGuard lock(s_s.m_nameMutex); VL_PRINTF_MT(" scopesDump:\n"); for (VerilatedScopeNameMap::const_iterator it=s_s.m_nameMap.begin(); it!=s_s.m_nameMap.end(); ++it) { const VerilatedScope* scopep = it->second; @@ -355,7 +350,7 @@ public: // But only for verilated*.cpp // miss at the cost of a multiply, and all lookups move to slowpath. static int exportInsert(const char* namep) VL_MT_SAFE { // Slow ok - called once/function at creation - VerilatedLockGuard guard(s_s.m_exportMutex); + VerilatedLockGuard lock(s_s.m_exportMutex); ExportNameMap::iterator it=s_s.m_exportMap.find(namep); if (it == s_s.m_exportMap.end()) { s_s.m_exportMap.insert(it, std::make_pair(namep, s_s.m_exportNext++)); @@ -365,7 +360,7 @@ public: // But only for verilated*.cpp } } static int exportFind(const char* namep) VL_MT_SAFE { - VerilatedLockGuard guard(s_s.m_exportMutex); + VerilatedLockGuard lock(s_s.m_exportMutex); ExportNameMap::const_iterator it=s_s.m_exportMap.find(namep); if (VL_LIKELY(it != s_s.m_exportMap.end())) return it->second; std::string msg = (std::string("%Error: Testbench C called ")+namep @@ -375,14 +370,14 @@ public: // But only for verilated*.cpp } static const char* exportName(int funcnum) VL_MT_SAFE { // Slowpath; find name for given export; errors only so no map to reverse-map it - VerilatedLockGuard guard(s_s.m_exportMutex); + VerilatedLockGuard lock(s_s.m_exportMutex); for (ExportNameMap::const_iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) { if (it->second == funcnum) return it->first; } return "*UNKNOWN*"; } static void exportsDump() VL_MT_SAFE { - VerilatedLockGuard guard(s_s.m_exportMutex); + VerilatedLockGuard lock(s_s.m_exportMutex); bool first = true; for (ExportNameMap::const_iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) { if (first) { VL_PRINTF_MT(" exportDump:\n"); first=false; } @@ -397,7 +392,7 @@ public: // But only for verilated*.cpp static IData fdNew(FILE* fp) VL_MT_SAFE { if (VL_UNLIKELY(!fp)) return 0; // Bit 31 indicates it's a descriptor not a MCD - VerilatedLockGuard guard(s_s.m_fdMutex); + VerilatedLockGuard lock(s_s.m_fdMutex); if (s_s.m_fdFree.empty()) { // Need to create more space in m_fdps and m_fdFree size_t start = s_s.m_fdps.size(); @@ -410,7 +405,7 @@ public: // But only for verilated*.cpp } static void fdDelete(IData fdi) VL_MT_SAFE { IData idx = VL_MASK_I(31) & fdi; - VerilatedLockGuard guard(s_s.m_fdMutex); + VerilatedLockGuard lock(s_s.m_fdMutex); if (VL_UNLIKELY(!(fdi & (1ULL<<31)) || idx >= s_s.m_fdps.size())) return; if (VL_UNLIKELY(!s_s.m_fdps[idx])) return; // Already free s_s.m_fdps[idx] = NULL; @@ -418,41 +413,10 @@ public: // But only for verilated*.cpp } static inline FILE* fdToFp(IData fdi) VL_MT_SAFE { IData idx = VL_MASK_I(31) & fdi; - VerilatedLockGuard guard(s_s.m_fdMutex); // This might get slow, if it does we can cache it + VerilatedLockGuard lock(s_s.m_fdMutex); // This might get slow, if it does we can cache it if (VL_UNLIKELY(!(fdi & (1ULL<<31)) || idx >= s_s.m_fdps.size())) return NULL; return s_s.m_fdps[idx]; } - -public: // But only for verilated*.cpp - // METHODS - Threading - static void numThreads(unsigned threads) VL_MT_SAFE { - VerilatedLockGuard guard(s_s.m_threadMutex); - if (!s_s.m_spawned) s_s.m_numThreads = threads; - } - static unsigned numThreads() VL_MT_SAFE { - VerilatedLockGuard guard(s_s.m_threadMutex); -#ifdef VL_THREADED - unsigned threads = s_s.m_numThreads; - if (threads == 0x0) { - threads = std::thread::hardware_concurrency(); // Or 0=unknown, C++11 - } - if (threads<1) threads = 1; - return threads; -#else - return 0; -#endif - } - static void spawnThreads() VL_MT_SAFE { - VerilatedLockGuard guard(s_s.m_threadMutex); - if (!s_s.m_spawned) { - // Convert numThreads from 0 to the spawned number - numThreads(numThreads()); - s_s.m_spawned = true; -#ifdef VL_THREADED - // THREADED-TODO startup threads -#endif - } - } }; //====================================================================== diff --git a/include/verilated_vcd_c.cpp b/include/verilated_vcd_c.cpp index 7899da295..8fb2701d4 100644 --- a/include/verilated_vcd_c.cpp +++ b/include/verilated_vcd_c.cpp @@ -61,18 +61,18 @@ private: static Singleton& singleton() { static Singleton s; return s; } public: static void pushVcd(VerilatedVcd* vcdp) VL_EXCLUDES(singleton().s_vcdMutex) { - VerilatedLockGuard guard(singleton().s_vcdMutex); + VerilatedLockGuard lock(singleton().s_vcdMutex); singleton().s_vcdVecp.push_back(vcdp); } static void removeVcd(const VerilatedVcd* vcdp) VL_EXCLUDES(singleton().s_vcdMutex) { - VerilatedLockGuard guard(singleton().s_vcdMutex); + VerilatedLockGuard lock(singleton().s_vcdMutex); VcdVec::iterator pos = find(singleton().s_vcdVecp.begin(), singleton().s_vcdVecp.end(), vcdp); if (pos != singleton().s_vcdVecp.end()) { singleton().s_vcdVecp.erase(pos); } } static void flush_all() VL_EXCLUDES(singleton().s_vcdMutex) VL_MT_UNSAFE_ONE { // Thread safety: Although this function is protected by a mutex so perhaps // in the future we can allow tracing in separate threads, vcdp->flush() assumes call from single thread - VerilatedLockGuard guard(singleton().s_vcdMutex); + VerilatedLockGuard lock(singleton().s_vcdMutex); for (VcdVec::const_iterator it=singleton().s_vcdVecp.begin(); it!=singleton().s_vcdVecp.end(); ++it) { VerilatedVcd* vcdp = *it; vcdp->flush();