From 61d6546400249ee4aae2fb8c55f979ea9d5288b0 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 11 Dec 2022 23:03:27 -0500 Subject: [PATCH] Internals: Mark more VL_MT_SAFE functions. No functional change --- include/verilated.cpp | 10 ++-- include/verilated.h | 3 +- include/verilated_cov.h | 8 +-- include/verilated_funcs.h | 93 ++++++++++++++++++----------------- include/verilated_trace_imp.h | 4 +- include/verilated_vpi.cpp | 3 +- 6 files changed, 63 insertions(+), 58 deletions(-) diff --git a/include/verilated.cpp b/include/verilated.cpp index eff55246c..679e948e1 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -595,7 +595,7 @@ double VL_ITOR_D_W(int lbits, const WDataInP lwp) VL_PURE { const double d = (hi + mid + lo) * std::exp2(VL_EDATASIZE * (ms_word - 2)); return d; } -double VL_ISTOR_D_W(int lbits, const WDataInP lwp) VL_PURE { +double VL_ISTOR_D_W(int lbits, const WDataInP lwp) VL_MT_SAFE { if (!VL_SIGN_W(lbits, lwp)) return VL_ITOR_D_W(lbits, lwp); uint32_t pos[VL_MULS_MAX_WORDS + 1]; // Fixed size, as MSVC++ doesn't allow [words] here VL_NEGATE_W(VL_WORDS_I(lbits), pos, lwp); @@ -1796,12 +1796,12 @@ std::string VL_TO_STRING_W(int words, const WDataInP obj) { return VL_SFORMATF_NX("'h%0x", words * VL_EDATASIZE, obj); } -std::string VL_TOLOWER_NN(const std::string& ld) VL_MT_SAFE { +std::string VL_TOLOWER_NN(const std::string& ld) VL_PURE { std::string out = ld; for (auto& cr : out) cr = std::tolower(cr); return out; } -std::string VL_TOUPPER_NN(const std::string& ld) VL_MT_SAFE { +std::string VL_TOUPPER_NN(const std::string& ld) VL_PURE { std::string out = ld; for (auto& cr : out) cr = std::toupper(cr); return out; @@ -2774,12 +2774,12 @@ static struct { VoidPCbList s_exitCbs VL_GUARDED_BY(s_exitMutex); } VlCbStatic; -static void addCb(Verilated::VoidPCb cb, void* datap, VoidPCbList& cbs) { +static void addCb(Verilated::VoidPCb cb, void* datap, VoidPCbList& cbs) VL_MT_UNSAFE { std::pair pair(cb, datap); cbs.remove(pair); // Just in case it's a duplicate cbs.push_back(pair); } -static void removeCb(Verilated::VoidPCb cb, void* datap, VoidPCbList& cbs) { +static void removeCb(Verilated::VoidPCb cb, void* datap, VoidPCbList& cbs) VL_MT_UNSAFE { std::pair pair(cb, datap); cbs.remove(pair); } diff --git a/include/verilated.h b/include/verilated.h index d1bc8c8f2..9186ed69c 100644 --- a/include/verilated.h +++ b/include/verilated.h @@ -856,7 +856,8 @@ public: // METHODS - INTERNAL USE ONLY (but public due to what uses it) // Internal: Create a new module name by concatenating two strings // Returns pointer to thread-local static data (overwritten on next call) - static const char* catName(const char* n1, const char* n2, const char* delimiter = "."); + static const char* catName(const char* n1, const char* n2, + const char* delimiter = ".") VL_MT_SAFE; // Internal: Throw signal assertion static void nullPointerError(const char* filename, int linenum) VL_ATTR_NORETURN VL_MT_SAFE; diff --git a/include/verilated_cov.h b/include/verilated_cov.h index bd92e064c..f3bde5eb4 100644 --- a/include/verilated_cov.h +++ b/include/verilated_cov.h @@ -128,15 +128,15 @@ public: #define K(n) const char* key##n #define A(n) const char *key##n, const char *valp##n // Argument list #define D(n) const char *key##n = nullptr, const char *valp##n = nullptr // Argument list - void _insertp(D(0), D(1), D(2), D(3), D(4), D(5), D(6), D(7), D(8), D(9)); + void _insertp(D(0), D(1), D(2), D(3), D(4), D(5), D(6), D(7), D(8), D(9)) VL_MT_SAFE; void _insertp(A(0), A(1), A(2), A(3), A(4), A(5), A(6), A(7), A(8), A(9), A(10), D(11), D(12), - D(13), D(14), D(15), D(16), D(17), D(18), D(19)); + D(13), D(14), D(15), D(16), D(17), D(18), D(19)) VL_MT_SAFE; void _insertp(A(0), A(1), A(2), A(3), A(4), A(5), A(6), A(7), A(8), A(9), A(10), A(11), A(12), A(13), A(14), A(15), A(16), A(17), A(18), A(19), A(20), D(21), D(22), D(23), - D(24), D(25), D(26), D(27), D(28), D(29)); + D(24), D(25), D(26), D(27), D(28), D(29)) VL_MT_SAFE; // Backward compatibility for Verilator void _insertp(A(0), A(1), K(2), int val2, K(3), int val3, K(4), const std::string& val4, A(5), - A(6), A(7)); + A(6), A(7)) VL_MT_SAFE; #undef K #undef A diff --git a/include/verilated_funcs.h b/include/verilated_funcs.h index fe6e98574..b8d30a793 100644 --- a/include/verilated_funcs.h +++ b/include/verilated_funcs.h @@ -37,24 +37,26 @@ /// User code may wish to replace this function, to do so, define VL_USER_FINISH. /// This code does not have to be thread safe. /// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this. -extern void vl_finish(const char* filename, int linenum, const char* hier); +extern void vl_finish(const char* filename, int linenum, const char* hier) VL_MT_UNSAFE; /// Routine to call for $stop and non-fatal error /// User code may wish to replace this function, to do so, define VL_USER_STOP. /// This code does not have to be thread safe. /// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this. -extern void vl_stop(const char* filename, int linenum, const char* hier); +extern void vl_stop(const char* filename, int linenum, const char* hier) VL_MT_UNSAFE; /// Routine to call for fatal messages /// User code may wish to replace this function, to do so, define VL_USER_FATAL. /// This code does not have to be thread safe. /// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this. -extern void vl_fatal(const char* filename, int linenum, const char* hier, const char* msg); +extern void vl_fatal(const char* filename, int linenum, const char* hier, + const char* msg) VL_MT_UNSAFE; /// Routine to call for warning messages /// User code may wish to replace this function, to do so, define VL_USER_WARN. /// This code does not have to be thread safe. -extern void vl_warn(const char* filename, int linenum, const char* hier, const char* msg); +extern void vl_warn(const char* filename, int linenum, const char* hier, + const char* msg) VL_MT_UNSAFE; //========================================================================= // Extern functions -- Slow path @@ -82,7 +84,7 @@ extern void VL_DBG_MSGF(const char* formatp, ...) VL_ATTR_PRINTF(1) VL_MT_SAFE; // EMIT_RULE: VL_RANDOM: oclean=dirty inline IData VL_RANDOM_I() VL_MT_SAFE { return vl_rand64(); } inline QData VL_RANDOM_Q() VL_MT_SAFE { return vl_rand64(); } -extern WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp); +extern WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp) VL_MT_SAFE; extern IData VL_RANDOM_SEEDED_II(IData& seedr) VL_MT_SAFE; extern IData VL_URANDOM_SEEDED_II(IData seed) VL_MT_SAFE; inline IData VL_URANDOM_RANGE_I(IData hi, IData lo) { @@ -100,52 +102,52 @@ inline IData VL_URANDOM_RANGE_I(IData hi, IData lo) { // These are init time only, so slow is fine /// Random reset a signal of given width -extern IData VL_RAND_RESET_I(int obits); +extern IData VL_RAND_RESET_I(int obits) VL_MT_SAFE; /// Random reset a signal of given width -extern QData VL_RAND_RESET_Q(int obits); +extern QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE; /// Random reset a signal of given width -extern WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp); +extern WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE; /// Zero reset a signal (slow - else use VL_ZERO_W) -extern WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp); +extern WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE; extern void VL_PRINTTIMESCALE(const char* namep, const char* timeunitp, const VerilatedContext* contextp) VL_MT_SAFE; extern WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP const lwp, WDataInP const rwp, - bool is_modulus); + bool is_modulus) VL_MT_SAFE; -extern IData VL_FGETS_IXI(int obits, void* destp, IData fpi); +extern IData VL_FGETS_IXI(int obits, void* destp, IData fpi) VL_MT_SAFE; -extern void VL_FFLUSH_I(IData fdi); -extern IData VL_FSEEK_I(IData fdi, IData offset, IData origin); -extern IData VL_FTELL_I(IData fdi); -extern void VL_FCLOSE_I(IData fdi); +extern void VL_FFLUSH_I(IData fdi) VL_MT_SAFE; +extern IData VL_FSEEK_I(IData fdi, IData offset, IData origin) VL_MT_SAFE; +extern IData VL_FTELL_I(IData fdi) VL_MT_SAFE; +extern void VL_FCLOSE_I(IData fdi) VL_MT_SAFE; extern IData VL_FREAD_I(int width, int array_lsb, int array_size, void* memp, IData fpi, - IData start, IData count); + IData start, IData count) VL_MT_SAFE; -extern void VL_WRITEF(const char* formatp, ...); -extern void VL_FWRITEF(IData fpi, const char* formatp, ...); +extern void VL_WRITEF(const char* formatp, ...) VL_MT_SAFE; +extern void VL_FWRITEF(IData fpi, const char* formatp, ...) VL_MT_SAFE; -extern IData VL_FSCANF_IX(IData fpi, const char* formatp, ...); -extern IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...); -extern IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...); -extern IData VL_SSCANF_IWX(int lbits, WDataInP const lwp, const char* formatp, ...); +extern IData VL_FSCANF_IX(IData fpi, const char* formatp, ...) VL_MT_SAFE; +extern IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...) VL_MT_SAFE; +extern IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...) VL_MT_SAFE; +extern IData VL_SSCANF_IWX(int lbits, WDataInP const lwp, const char* formatp, ...) VL_MT_SAFE; -extern void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...); -extern void VL_SFORMAT_X(int obits, SData& destr, const char* formatp, ...); -extern void VL_SFORMAT_X(int obits, IData& destr, const char* formatp, ...); -extern void VL_SFORMAT_X(int obits, QData& destr, const char* formatp, ...); -extern void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...); +extern void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...) VL_MT_SAFE; +extern void VL_SFORMAT_X(int obits, SData& destr, const char* formatp, ...) VL_MT_SAFE; +extern void VL_SFORMAT_X(int obits, IData& destr, const char* formatp, ...) VL_MT_SAFE; +extern void VL_SFORMAT_X(int obits, QData& destr, const char* formatp, ...) VL_MT_SAFE; +extern void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) VL_MT_SAFE; extern void VL_STACKTRACE() VL_MT_SAFE; extern std::string VL_STACKTRACE_N() VL_MT_SAFE; -extern IData VL_SYSTEM_IW(int lhswords, WDataInP const lhsp); -extern IData VL_SYSTEM_IQ(QData lhs); +extern IData VL_SYSTEM_IW(int lhswords, WDataInP const lhsp) VL_MT_SAFE; +extern IData VL_SYSTEM_IQ(QData lhs) VL_MT_SAFE; inline IData VL_SYSTEM_II(IData lhs) VL_MT_SAFE { return VL_SYSTEM_IQ(lhs); } -extern IData VL_TESTPLUSARGS_I(const std::string& format); -extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish +extern IData VL_TESTPLUSARGS_I(const std::string& format) VL_MT_SAFE; +extern const char* vl_mc_scan_plusargs(const char* prefixp) VL_MT_SAFE; // PLIish //========================================================================= // Base macros @@ -214,14 +216,14 @@ static inline double VL_ITOR_D_Q(int, QData lhs) VL_PURE { return static_cast(static_cast(lhs)); } // Return double from lhs (numeric) signed -double VL_ISTOR_D_W(int lbits, WDataInP const lwp) VL_PURE; -static inline double VL_ISTOR_D_I(int lbits, IData lhs) VL_PURE { +double VL_ISTOR_D_W(int lbits, WDataInP const lwp) VL_MT_SAFE; +static inline double VL_ISTOR_D_I(int lbits, IData lhs) VL_MT_SAFE { if (lbits == 32) return static_cast(static_cast(lhs)); VlWide lwp; VL_SET_WI(lwp, lhs); return VL_ISTOR_D_W(lbits, lwp); } -static inline double VL_ISTOR_D_Q(int lbits, QData lhs) VL_PURE { +static inline double VL_ISTOR_D_Q(int lbits, QData lhs) VL_MT_SAFE { if (lbits == 64) return static_cast(static_cast(lhs)); VlWide lwp; VL_SET_WQ(lwp, lhs); @@ -249,7 +251,7 @@ static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) VL_PURE { } // Debugging prints -extern void _vl_debug_print_w(int lbits, WDataInP const iwp); +extern void _vl_debug_print_w(int lbits, WDataInP const iwp) VL_MT_SAFE; //========================================================================= // Pli macros @@ -1158,9 +1160,10 @@ static inline QData VL_POW_QQQ(int, int, int rbits, QData lhs, QData rhs) VL_PUR return out; } WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP const lwp, - WDataInP const rwp); -WDataOutP VL_POW_WWQ(int obits, int, int rbits, WDataOutP owp, WDataInP const lwp, QData rhs); -QData VL_POW_QQW(int obits, int, int rbits, QData lhs, WDataInP const rwp); + WDataInP const rwp) VL_MT_SAFE; +WDataOutP VL_POW_WWQ(int obits, int, int rbits, WDataOutP owp, WDataInP const lwp, + QData rhs) VL_MT_SAFE; +QData VL_POW_QQW(int obits, int, int rbits, QData lhs, WDataInP const rwp) VL_MT_SAFE; #define VL_POWSS_IIQ(obits, lbits, rbits, lhs, rhs, lsign, rsign) \ VL_POWSS_QQQ(obits, lbits, rbits, lhs, rhs, lsign, rsign) @@ -1212,11 +1215,11 @@ static inline QData VL_POWSS_QQQ(int obits, int, int rbits, QData lhs, QData rhs return VL_POW_QQQ(obits, rbits, rbits, lhs, rhs); } WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP const lwp, - WDataInP const rwp, bool lsign, bool rsign); + WDataInP const rwp, bool lsign, bool rsign) VL_MT_SAFE; WDataOutP VL_POWSS_WWQ(int obits, int, int rbits, WDataOutP owp, WDataInP const lwp, QData rhs, - bool lsign, bool rsign); + bool lsign, bool rsign) VL_MT_SAFE; QData VL_POWSS_QQW(int obits, int, int rbits, QData lhs, WDataInP const rwp, bool lsign, - bool rsign); + bool rsign) VL_MT_SAFE; //=================================================================== // Concat/replication @@ -1943,7 +1946,7 @@ static inline QData VL_RTOIROUND_Q_D(double lhs) VL_PURE { static inline IData VL_RTOIROUND_I_D(double lhs) VL_PURE { return static_cast(VL_RTOIROUND_Q_D(lhs)); } -static inline WDataOutP VL_RTOIROUND_W_D(int obits, WDataOutP owp, double lhs) VL_PURE { +static inline WDataOutP VL_RTOIROUND_W_D(int obits, WDataOutP owp, double lhs) VL_MT_SAFE { // IEEE format: [63]=sign [62:52]=exp+1023 [51:0]=mantissa // This does not need to support subnormals as they are sub-integral lhs = VL_ROUND(lhs); @@ -2153,7 +2156,7 @@ inline IData VL_CMP_NN(const std::string& lhs, const std::string& rhs, bool igno extern IData VL_ATOI_N(const std::string& str, int base) VL_PURE; -extern IData VL_FGETS_NI(std::string& dest, IData fpi); +extern IData VL_FGETS_NI(std::string& dest, IData fpi) VL_MT_SAFE; //====================================================================== // Dist functions @@ -2196,8 +2199,8 @@ inline std::string VL_REPLICATEN_NNI(const std::string& lhs, IData rep) VL_PURE } inline IData VL_LEN_IN(const std::string& ld) { return ld.length(); } -extern std::string VL_TOLOWER_NN(const std::string& ld); -extern std::string VL_TOUPPER_NN(const std::string& ld); +extern std::string VL_TOLOWER_NN(const std::string& ld) VL_PURE; +extern std::string VL_TOUPPER_NN(const std::string& ld) VL_PURE; extern IData VL_FERROR_IN(IData fpi, std::string& outputr) VL_MT_SAFE; extern IData VL_FOPEN_NN(const std::string& filename, const std::string& mode) VL_MT_SAFE; diff --git a/include/verilated_trace_imp.h b/include/verilated_trace_imp.h index d925bcaf4..2aba690b5 100644 --- a/include/verilated_trace_imp.h +++ b/include/verilated_trace_imp.h @@ -41,7 +41,7 @@ //============================================================================= // Static utility functions -static double timescaleToDouble(const char* unitp) { +static double timescaleToDouble(const char* unitp) VL_PURE { char* endp = nullptr; double value = std::strtod(unitp, &endp); // On error so we allow just "ns" to return 1e-9. @@ -60,7 +60,7 @@ static double timescaleToDouble(const char* unitp) { return value; } -static std::string doubleToTimescale(double value) { +static std::string doubleToTimescale(double value) VL_PURE { const char* suffixp = "s"; // clang-format off if (value >= 1e0) { suffixp = "s"; value *= 1e0; } diff --git a/include/verilated_vpi.cpp b/include/verilated_vpi.cpp index 85358d731..ffabf253f 100644 --- a/include/verilated_vpi.cpp +++ b/include/verilated_vpi.cpp @@ -2290,7 +2290,8 @@ PLI_INT32 vpi_release_handle(vpiHandle object) { return 1; } -PLI_INT32 vpi_get_vlog_info(p_vpi_vlog_info vlog_info_p) VL_MT_SAFE { +PLI_INT32 vpi_get_vlog_info(p_vpi_vlog_info vlog_info_p) { + // This is VL_MT_SAFE, but not marked as can't indicate it in the standardized header file VerilatedVpiImp::assertOneCheck(); VL_VPI_ERROR_RESET_(); const auto argc_argv = Verilated::threadContextp()->impp()->argc_argv();