Internals: Add VL_MT_SAFE attribute to functions that requires locking. (#3805)

This commit is contained in:
Kamil Rakoczy 2023-03-18 01:24:15 +01:00 committed by GitHub
parent d6c5d40f9b
commit 798d7346cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 185 additions and 143 deletions

View File

@ -68,7 +68,7 @@ public:
: V3GraphVertex{graphp}
, m_name{name}
, m_type{type} {}
string name() const override { return m_name + " " + typestr(); }
string name() const override VL_MT_STABLE { return m_name + " " + typestr(); }
string dotColor() const override { return user() ? "green" : "black"; }
virtual int type() const { return m_type; }
};

View File

@ -125,7 +125,9 @@ string AstNode::encodeNumber(int64_t num) {
}
}
string AstNode::nameProtect() const { return VIdProtect::protectIf(name(), protect()); }
string AstNode::nameProtect() const VL_MT_STABLE {
return VIdProtect::protectIf(name(), protect());
}
string AstNode::origNameProtect() const { return VIdProtect::protectIf(origName(), protect()); }
string AstNode::shortName() const {

View File

@ -1670,7 +1670,7 @@ public:
static constexpr int INSTR_COUNT_PLI = 20; // PLI routines
// ACCESSORS
virtual string name() const VL_MT_SAFE { return ""; }
virtual string name() const VL_MT_STABLE { return ""; }
virtual string origName() const { return ""; }
virtual void name(const string& name) {
this->v3fatalSrc("name() called on object without name() method");
@ -1678,7 +1678,7 @@ public:
virtual void tag(const string& text) {}
virtual string tag() const { return ""; }
virtual string verilogKwd() const { return ""; }
string nameProtect() const; // Name with --protect-id applied
string nameProtect() const VL_MT_STABLE; // Name with --protect-id applied
string origNameProtect() const; // origName with --protect-id applied
string shortName() const; // Name with __PVT__ removed for concatenating scopes
static string dedotName(const string& namein); // Name with dots removed
@ -1691,7 +1691,7 @@ public:
encodeName(const string& namein); // Encode user name into internal C representation
static string encodeNumber(int64_t num); // Encode number into internal C representation
static string vcdName(const string& namein); // Name for printing out to vcd files
string prettyName() const VL_MT_SAFE { return prettyName(name()); }
string prettyName() const VL_MT_STABLE { return prettyName(name()); }
string prettyNameQ() const { return prettyNameQ(name()); }
string prettyTypeName() const; // "VARREF" for error messages (NOT dtype's pretty name)
virtual string prettyOperatorName() const { return "operator " + prettyTypeName(); }

View File

@ -242,7 +242,7 @@ public:
bool similarDType(const AstNodeDType* samep) const override {
return this == samep; // We don't compare members, require exact equivalence
}
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
void name(const string& flag) override { m_name = flag; }
bool packed() const VL_MT_SAFE { return m_packed; }
void packed(bool flag) { m_packed = flag; }
@ -281,7 +281,7 @@ public:
this->valuep(valuep);
}
ASTGEN_MEMBERS_AstEnumItem;
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
bool maybePointedTo() const override { return true; }
bool hasDType() const override { return true; }
void name(const string& flag) override { m_name = flag; }
@ -409,7 +409,7 @@ public:
bool similarDType(const AstNodeDType* samep) const override {
return type() == samep->type() && same(samep);
}
string name() const override { return m.m_keyword.ascii(); }
string name() const override VL_MT_STABLE { return m.m_keyword.ascii(); }
string prettyDTypeName() const override;
const char* broken() const override {
BROKEN_RTN(dtypep() != this);
@ -531,7 +531,7 @@ public:
}
void dump(std::ostream& str = std::cout) const override;
void dumpSmall(std::ostream& str) const override;
string name() const override;
string name() const override VL_MT_STABLE;
AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; }
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
@ -543,7 +543,7 @@ public:
AstNodeDType* subDTypep() const override VL_MT_SAFE { return nullptr; }
AstNodeModule* classOrPackagep() const { return m_classOrPackagep; }
void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; }
AstClass* classp() const { return m_classp; }
AstClass* classp() const VL_MT_STABLE { return m_classp; }
void classp(AstClass* nodep) { m_classp = nodep; }
bool isCompound() const override { return true; }
};
@ -641,7 +641,7 @@ public:
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
int widthAlignBytes() const override { return dtypep()->widthAlignBytes(); }
int widthTotalBytes() const override { return dtypep()->widthTotalBytes(); }
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
void name(const string& flag) override { m_name = flag; }
bool isCompound() const override { return false; }
};
@ -767,7 +767,7 @@ public:
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
void name(const string& flag) override { m_name = flag; }
void dump(std::ostream& str = std::cout) const override;
void dumpSmall(std::ostream& str) const override;
@ -879,7 +879,7 @@ public:
}
ASTGEN_MEMBERS_AstMemberDType;
void dumpSmall(std::ostream& str) const override;
string name() const override { return m_name; } // * = Var name
string name() const override VL_MT_STABLE { return m_name; } // * = Var name
bool hasDType() const override { return true; }
bool maybePointedTo() const override { return true; }
const char* broken() const override {
@ -955,7 +955,7 @@ public:
int widthAlignBytes() const override { return dtypep()->widthAlignBytes(); }
int widthTotalBytes() const override { return dtypep()->widthTotalBytes(); }
// METHODS
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
bool maybePointedTo() const override { return true; }
bool hasDType() const override { return true; }
void name(const string& flag) override { m_name = flag; }
@ -1093,7 +1093,7 @@ public:
}
void dump(std::ostream& str = std::cout) const override;
void dumpSmall(std::ostream& str) const override;
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
string prettyDTypeName() const override {
return subDTypep() ? prettyName(subDTypep()->name()) : prettyName();
}

View File

@ -236,7 +236,7 @@ public:
const char* broken() const override;
void cloneRelink() override;
void dump(std::ostream& str = std::cout) const override;
string name() const override { return m_name; } // * = Var name
string name() const override VL_MT_STABLE { return m_name; } // * = Var name
bool isGateOptimizable() const override;
string dotted() const { return m_dotted; } // * = Scope name or ""
string inlinedDots() const { return m_inlinedDots; }
@ -474,7 +474,7 @@ public:
const char* broken() const override;
int instrCount() const override { return widthInstrs(); }
void cloneRelink() override;
string name() const override { return m_name; } // * = Var name
string name() const override VL_MT_STABLE { return m_name; } // * = Var name
void name(const string& name) override { m_name = name; }
VAccess access() const { return m_access; }
void access(const VAccess& flag) { m_access = flag; } // Avoid using this; Set in constructor
@ -532,7 +532,7 @@ public:
}
ASTGEN_MEMBERS_AstArg;
bool hasDType() const override { return false; }
string name() const override { return m_name; } // * = Pin name, ""=go by number
string name() const override VL_MT_STABLE { return m_name; } // * = Pin name, ""=go by number
void name(const string& name) override { m_name = name; }
bool emptyConnectNoNext() const { return !exprp() && name() == "" && !nextp(); }
@ -610,7 +610,7 @@ public:
this->addPinsp(pinsp);
}
ASTGEN_MEMBERS_AstCMethodHard;
string name() const override { return m_name; } // * = Var name
string name() const override VL_MT_STABLE { return m_name; } // * = Var name
void name(const string& name) override { m_name = name; }
bool same(const AstNode* samep) const override {
const AstCMethodHard* asamep = static_cast<const AstCMethodHard*>(samep);
@ -689,7 +689,7 @@ public:
}
ASTGEN_MEMBERS_AstCellArrayRef;
// ACCESSORS
string name() const override { return m_name; } // * = Array name
string name() const override VL_MT_STABLE { return m_name; } // * = Array name
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); }
@ -710,7 +710,7 @@ public:
}
ASTGEN_MEMBERS_AstCellRef;
// ACCESSORS
string name() const override { return m_name; } // * = Array name
string name() const override VL_MT_STABLE { return m_name; } // * = Array name
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); }
@ -746,7 +746,7 @@ public:
== static_cast<const AstClassOrPackageRef*>(samep)->m_classOrPackageNodep);
}
void dump(std::ostream& str = std::cout) const override;
string name() const override { return m_name; } // * = Var name
string name() const override VL_MT_STABLE { return m_name; } // * = Var name
AstNode* classOrPackageNodep() const { return m_classOrPackageNodep; }
void classOrPackageNodep(AstNode* nodep) { m_classOrPackageNodep = nodep; }
AstNodeModule* classOrPackagep() const;
@ -990,7 +990,7 @@ public:
initWithNumber();
}
ASTGEN_MEMBERS_AstConst;
string name() const override { return num().ascii(); } // * = Value
string name() const override VL_MT_STABLE { return num().ascii(); } // * = Value
const V3Number& num() const VL_MT_SAFE { return m_num; } // * = Value
V3Number& num() { return m_num; } // * = Value
uint32_t toUInt() const { return num().toUInt(); }
@ -1058,7 +1058,7 @@ public:
}
ASTGEN_MEMBERS_AstEnumItemRef;
void dump(std::ostream& str) const override;
string name() const override { return itemp()->name(); }
string name() const override VL_MT_STABLE { return itemp()->name(); }
int instrCount() const override { return 0; }
const char* broken() const override;
void cloneRelink() override {
@ -1068,7 +1068,7 @@ public:
const AstEnumItemRef* const sp = static_cast<const AstEnumItemRef*>(samep);
return itemp() == sp->itemp();
}
AstEnumItem* itemp() const { return m_itemp; }
AstEnumItem* itemp() const VL_MT_STABLE { return m_itemp; }
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); }
bool cleanOut() const override { return true; }
@ -1209,7 +1209,7 @@ public:
this->filep(filep);
}
ASTGEN_MEMBERS_AstFScanF;
string name() const override { return m_text; }
string name() const override VL_MT_STABLE { return m_text; }
string verilogKwd() const override { return "$fscanf"; }
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); }
@ -1406,7 +1406,7 @@ public:
string emitC() override { V3ERROR_NA_RETURN(""); }
bool cleanOut() const override { return true; }
int instrCount() const override { return widthInstrs(); }
string name() const override { return m_name; } // * = Var name
string name() const override VL_MT_STABLE { return m_name; } // * = Var name
void name(const string& name) override { m_name = name; }
bool index() const { return m_index; }
};
@ -1432,7 +1432,7 @@ public:
void cloneRelink() override;
const char* broken() const override;
void dump(std::ostream& str) const override;
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
void name(const string& name) override { m_name = name; }
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); }
@ -1497,7 +1497,7 @@ public:
}
ASTGEN_MEMBERS_AstParseRef;
void dump(std::ostream& str) const override;
string name() const override { return m_name; } // * = Var name
string name() const override VL_MT_STABLE { return m_name; } // * = Var name
bool same(const AstNode* samep) const override {
const AstParseRef* const asamep = static_cast<const AstParseRef*>(samep);
return (expect() == asamep->expect() && m_name == asamep->m_name);
@ -1671,7 +1671,7 @@ public:
addExprsp(exprsp);
}
ASTGEN_MEMBERS_AstSFormatF;
string name() const override { return m_text; }
string name() const override VL_MT_STABLE { return m_text; }
int instrCount() const override { return INSTR_COUNT_PLI; }
bool same(const AstNode* samep) const override {
return text() == static_cast<const AstSFormatF*>(samep)->text();
@ -1706,7 +1706,7 @@ public:
this->fromp(fromp);
}
ASTGEN_MEMBERS_AstSScanF;
string name() const override { return m_text; }
string name() const override VL_MT_STABLE { return m_text; }
string verilogKwd() const override { return "$sscanf"; }
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); }
@ -1891,7 +1891,7 @@ public:
dtypep(nullptr); // V3Width will resolve
}
ASTGEN_MEMBERS_AstStructSel;
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
void name(const string& name) override { m_name = name; }
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); }
@ -2200,7 +2200,7 @@ public:
void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
out.opCompareNN(lhs, rhs, m_ignoreCase);
}
string name() const override { return m_ignoreCase ? "icompare" : "compare"; }
string name() const override VL_MT_STABLE { return m_ignoreCase ? "icompare" : "compare"; }
string emitVerilog() override {
return m_ignoreCase ? "%k(%l.icompare(%r))" : "%k(%l.compare(%r))";
}
@ -2424,7 +2424,7 @@ public:
void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
out.opGetcN(lhs, rhs);
}
string name() const override { return "getc"; }
string name() const override VL_MT_STABLE { return "getc"; }
string emitVerilog() override { return "%k(%l.getc(%r))"; }
string emitC() override { return "VL_GETC_N(%li,%ri)"; }
string emitSimpleOperator() override { return ""; }
@ -4304,7 +4304,7 @@ public:
const V3Number& ths) override {
out.opPutcN(lhs, rhs, ths);
}
string name() const override { return "putc"; }
string name() const override VL_MT_STABLE { return "putc"; }
string emitVerilog() override { return "%k(%l.putc(%r,%t))"; }
string emitC() override { return "VL_PUTC_N(%li,%ri,%ti)"; }
string emitSimpleOperator() override { return ""; }
@ -4411,7 +4411,7 @@ public:
const V3Number& ths) override {
out.opSubstrN(lhs, rhs, ths);
}
string name() const override { return "substr"; }
string name() const override VL_MT_STABLE { return "substr"; }
string emitVerilog() override { return "%k(%l.substr(%r,%t))"; }
string emitC() override { return "VL_SUBSTR_N(%li,%ri,%ti)"; }
string emitSimpleOperator() override { return ""; }
@ -4488,7 +4488,7 @@ public:
}
ASTGEN_MEMBERS_AstAtoN;
void numberOperate(V3Number& out, const V3Number& lhs) override { out.opAtoN(lhs, m_fmt); }
string name() const override {
string name() const override VL_MT_STABLE {
switch (m_fmt) {
case ATOI: return "atoi";
case ATOHEX: return "atohex";

View File

@ -48,7 +48,7 @@ protected:
public:
ASTGEN_MEMBERS_AstNodeBlock;
void dump(std::ostream& str) const override;
string name() const override { return m_name; } // * = Block name
string name() const override VL_MT_STABLE { return m_name; } // * = Block name
void name(const string& name) override { m_name = name; }
bool unnamed() const { return m_unnamed; }
bool isFirstInMyListOfStatements(AstNode* nodep) const override { return nodep == stmtsp(); }
@ -118,7 +118,7 @@ protected:
public:
ASTGEN_MEMBERS_AstNodeFTask;
void dump(std::ostream& str = std::cout) const override;
string name() const override { return m_name; } // * = Var name
string name() const override VL_MT_STABLE { return m_name; } // * = Var name
bool maybePointedTo() const override { return true; }
bool isGateOptimizable() const override { return !((m_dpiExport || m_dpiImport) && !m_pure); }
// {AstFunc only} op1 = Range output variable
@ -186,7 +186,7 @@ public:
, m_name{name} {}
ASTGEN_MEMBERS_AstNodeFile;
void dump(std::ostream& str) const override;
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
bool same(const AstNode* /*samep*/) const override { return true; }
};
class AstNodeModule VL_NOT_FINAL : public AstNode {
@ -234,7 +234,7 @@ public:
ASTGEN_MEMBERS_AstNodeModule;
void dump(std::ostream& str) const override;
bool maybePointedTo() const override { return true; }
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
virtual bool timescaleMatters() const = 0;
// ACCESSORS
void name(const string& name) override { m_name = name; }
@ -373,7 +373,7 @@ public:
this->addPasssp(passsp);
}
ASTGEN_MEMBERS_AstNodeCoverOrAssert;
string name() const override { return m_name; } // * = Var name
string name() const override VL_MT_STABLE { return m_name; } // * = Var name
bool same(const AstNode* samep) const override { return samep->name() == name(); }
void name(const string& name) override { m_name = name; }
void dump(std::ostream& str = std::cout) const override;
@ -512,7 +512,7 @@ public:
}
ASTGEN_MEMBERS_AstActive;
void dump(std::ostream& str = std::cout) const override;
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
const char* broken() const override;
void cloneRelink() override;
// Statements are broken into pieces, as some must come before others.
@ -537,7 +537,7 @@ public:
}
ASTGEN_MEMBERS_AstBind;
// ACCESSORS
string name() const override { return m_name; } // * = Bind Target name
string name() const override VL_MT_STABLE { return m_name; } // * = Bind Target name
void name(const string& name) override { m_name = name; }
};
class AstCFunc final : public AstNode {
@ -607,7 +607,7 @@ public:
m_dpiTraceInit = false;
}
ASTGEN_MEMBERS_AstCFunc;
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
const char* broken() const override;
void cloneRelink() override;
bool maybePointedTo() const override { return true; }
@ -702,7 +702,7 @@ public:
, m_useType{useType} {}
ASTGEN_MEMBERS_AstCUse;
void dump(std::ostream& str = std::cout) const override;
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
VUseType useType() const { return m_useType; }
};
class AstCaseItem final : public AstNode {
@ -755,7 +755,7 @@ public:
const char* broken() const override;
bool maybePointedTo() const override { return true; }
// ACCESSORS
string name() const override { return m_name; } // * = Cell name
string name() const override VL_MT_STABLE { return m_name; } // * = Cell name
void name(const string& name) override { m_name = name; }
string origName() const override { return m_origName; } // * = Original name
void origName(const string& name) { m_origName = name; }
@ -794,7 +794,7 @@ public:
void dump(std::ostream& str) const override;
const char* broken() const override;
// ACCESSORS
string name() const override { return m_name; } // * = Cell name
string name() const override VL_MT_STABLE { return m_name; } // * = Cell name
string origModName() const { return m_origModName; } // * = modp()->origName() before inlining
void name(const string& name) override { m_name = name; }
void scopep(AstScope* scp) { m_scopep = scp; }
@ -845,7 +845,7 @@ public:
}
ASTGEN_MEMBERS_AstClocking;
void dump(std::ostream& str) const override;
std::string name() const override { return m_name; }
std::string name() const override VL_MT_STABLE { return m_name; }
bool isDefault() const { return m_isDefault; }
bool isGlobal() const { return m_isGlobal; }
};
@ -916,7 +916,7 @@ public:
, m_path{path} {
this->rhsp(rhsp);
}
string name() const override { return m_name; } // * = Scope name
string name() const override VL_MT_STABLE { return m_name; } // * = Scope name
ASTGEN_MEMBERS_AstDefParam;
bool same(const AstNode*) const override { return true; }
string path() const { return m_path; }
@ -934,7 +934,7 @@ public:
, m_name{vname}
, m_cname{cname} {}
ASTGEN_MEMBERS_AstDpiExport;
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
void name(const string& name) override { m_name = name; }
string cname() const { return m_cname; }
void cname(const string& cname) { m_cname = cname; }
@ -995,7 +995,7 @@ public:
BROKEN_RTN(!m_depGraphp);
return nullptr;
}
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
V3Graph* depGraphp() { return m_depGraphp; }
const V3Graph* depGraphp() const { return m_depGraphp; }
};
@ -1033,7 +1033,7 @@ public:
AstIntfRef(FileLine* fl, const string& name)
: ASTGEN_SUPER_IntfRef(fl)
, m_name{name} {}
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
ASTGEN_MEMBERS_AstIntfRef;
};
class AstMTaskBody final : public AstNode {
@ -1070,7 +1070,7 @@ public:
, m_name{name} {
this->addVarsp(varsp);
}
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
bool maybePointedTo() const override { return true; }
ASTGEN_MEMBERS_AstModport;
};
@ -1092,7 +1092,7 @@ public:
const char* broken() const override;
void cloneRelink() override;
void dump(std::ostream& str) const override;
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
bool isImport() const { return !m_export; }
bool isExport() const { return m_export; }
AstNodeFTask* ftaskp() const { return m_ftaskp; } // [After Link] Pointer to variable
@ -1115,7 +1115,7 @@ public:
const char* broken() const override;
void cloneRelink() override;
void dump(std::ostream& str) const override;
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
void direction(const VDirection& flag) { m_direction = flag; }
VDirection direction() const { return m_direction; }
AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable
@ -1149,7 +1149,7 @@ public:
ASTGEN_MEMBERS_AstNetlist;
const char* broken() const override;
void cloneRelink() override { V3ERROR_NA; }
string name() const override { return "$root"; }
string name() const override VL_MT_STABLE { return "$root"; }
void dump(std::ostream& str) const override;
AstNodeModule* topModulep() const { // Top module in hierarchy
return modulesp(); // First one in the list, for now
@ -1198,7 +1198,7 @@ public:
const char* broken() const override;
void cloneRelink() override;
void dump(std::ostream& str) const override;
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
AstPackage* packagep() const { return m_packagep; }
void packagep(AstPackage* nodep) { m_packagep = nodep; }
};
@ -1224,7 +1224,7 @@ public:
const char* broken() const override;
void cloneRelink() override;
void dump(std::ostream& str) const override;
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
AstPackage* packagep() const { return m_packagep; }
void packagep(AstPackage* nodep) { m_packagep = nodep; }
};
@ -1250,7 +1250,7 @@ public:
ASTGEN_MEMBERS_AstPin;
void dump(std::ostream& str) const override;
const char* broken() const override;
string name() const override { return m_name; } // * = Pin name, ""=go by number
string name() const override VL_MT_STABLE { return m_name; } // * = Pin name, ""=go by number
void name(const string& name) override { m_name = name; }
string prettyOperatorName() const override;
bool dotStar() const { return name() == ".*"; } // Fake name for .* connections until linked
@ -1278,7 +1278,7 @@ public:
, m_pinNum{pinnum}
, m_name{name} {}
ASTGEN_MEMBERS_AstPort;
string name() const override { return m_name; } // * = Port name
string name() const override VL_MT_STABLE { return m_name; } // * = Port name
int pinNum() const { return m_pinNum; } // * = Pin number, for order based instantiation
};
class AstPragma final : public AstNode {
@ -1356,7 +1356,7 @@ public:
void cloneRelink() override;
const char* broken() const override;
bool maybePointedTo() const override { return true; }
string name() const override { return m_name; } // * = Scope name
string name() const override VL_MT_STABLE { return m_name; } // * = Scope name
void name(const string& name) override { m_name = name; }
void dump(std::ostream& str) const override;
string nameDotless() const;
@ -1548,7 +1548,7 @@ public:
return dtypep() ? dtypep() : childDTypep();
}
// METHODS
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
bool maybePointedTo() const override { return true; }
bool hasDType() const override { return true; }
void name(const string& flag) override { m_name = flag; }
@ -1568,7 +1568,7 @@ public:
, m_name{name} {}
ASTGEN_MEMBERS_AstTypedefFwd;
// METHODS
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
bool maybePointedTo() const override { return true; }
};
class AstUdpTable final : public AstNode {
@ -1588,7 +1588,7 @@ public:
: ASTGEN_SUPER_UdpTableLine(fl)
, m_text{text} {}
ASTGEN_MEMBERS_AstUdpTableLine;
string name() const override { return m_text; }
string name() const override VL_MT_STABLE { return m_text; }
string text() const { return m_text; }
};
class AstVar final : public AstNode {
@ -1758,7 +1758,7 @@ public:
}
ASTGEN_MEMBERS_AstVar;
void dump(std::ostream& str) const override;
string name() const override VL_MT_SAFE { return m_name; } // * = Var name
string name() const override VL_MT_STABLE VL_MT_SAFE { return m_name; } // * = Var name
bool hasDType() const override { return true; }
bool maybePointedTo() const override { return true; }
string origName() const override { return m_origName; } // * = Original name
@ -1998,7 +1998,7 @@ public:
return nullptr;
}
bool maybePointedTo() const override { return true; }
string name() const override { return scopep()->name() + "->" + varp()->name(); }
string name() const override VL_MT_STABLE { return scopep()->name() + "->" + varp()->name(); }
void dump(std::ostream& str) const override;
bool hasDType() const override { return true; }
AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable
@ -2452,7 +2452,7 @@ public:
, m_name{name}
, m_showAt{showAt} {}
ASTGEN_MEMBERS_AstComment;
string name() const override { return m_name; } // * = Text
string name() const override VL_MT_STABLE { return m_name; } // * = Text
bool same(const AstNode* samep) const override { return true; } // Ignore name in comments
virtual bool showAt() const { return m_showAt; }
};
@ -2593,7 +2593,7 @@ public:
: ASTGEN_SUPER_Disable(fl)
, m_name{name} {}
ASTGEN_MEMBERS_AstDisable;
string name() const override { return m_name; } // * = Block name
string name() const override VL_MT_STABLE { return m_name; } // * = Block name
void name(const string& flag) override { m_name = flag; }
bool isBrancher() const override {
return true; // SPECIAL: We don't process code after breaks
@ -2884,7 +2884,7 @@ public:
: ASTGEN_SUPER_PrintTimeScale(fl) {}
ASTGEN_MEMBERS_AstPrintTimeScale;
void name(const string& name) override { m_name = name; }
string name() const override { return m_name; } // * = Var name
string name() const override VL_MT_STABLE { return m_name; } // * = Var name
void dump(std::ostream& str) const override;
string verilogKwd() const override { return "$printtimescale"; }
bool isGateOptimizable() const override { return false; }
@ -3103,7 +3103,7 @@ public:
void dump(std::ostream& str) const override;
int instrCount() const override { return 100; } // Large...
ASTGEN_MEMBERS_AstTraceDecl;
string name() const override { return m_showname; }
string name() const override VL_MT_STABLE { return m_showname; }
bool maybePointedTo() const override { return true; }
bool hasDType() const override { return true; }
bool same(const AstNode* samep) const override { return false; }

View File

@ -40,25 +40,31 @@ template <typename T>
class V3ConfigWildcardResolver final {
using Map = std::map<const std::string, T>;
Map m_mapWildcard; // Wildcard strings to entities
Map m_mapResolved; // Resolved strings to converged entities
mutable VerilatedMutex m_mutex; // protects members
Map m_mapWildcard VL_GUARDED_BY(m_mutex); // Wildcard strings to entities
Map m_mapResolved VL_GUARDED_BY(m_mutex); // Resolved strings to converged entities
public:
V3ConfigWildcardResolver() = default;
~V3ConfigWildcardResolver() = default;
/// Update into maps from other
void update(const V3ConfigWildcardResolver& other) {
void update(const V3ConfigWildcardResolver& other) VL_MT_SAFE_EXCLUDES(m_mutex)
VL_EXCLUDES(other.m_mutex) {
VerilatedLockGuard lock{m_mutex};
VerilatedLockGuard otherLock{other.m_mutex};
for (const auto& itr : other.m_mapResolved) m_mapResolved[itr.first].update(itr.second);
for (const auto& itr : other.m_mapWildcard) m_mapWildcard[itr.first].update(itr.second);
}
// Access and create a (wildcard) entity
T& at(const string& name) {
T& at(const string& name) VL_MT_SAFE_EXCLUDES(m_mutex) {
VerilatedLockGuard lock{m_mutex};
// Don't store into wildcards if the name is not a wildcard string
return m_mapWildcard[name];
}
// Access an entity and resolve wildcards that match it
T* resolve(const string& name) {
T* resolve(const string& name) VL_MT_SAFE_EXCLUDES(m_mutex) {
VerilatedLockGuard lock{m_mutex};
// Lookup if it was resolved before, typically not
auto it = m_mapResolved.find(name);
if (VL_UNLIKELY(it != m_mapResolved.end())) return &it->second;
@ -78,7 +84,10 @@ public:
return newp;
}
// Flush on update
void flush() { m_mapResolved.clear(); }
void flush() VL_MT_SAFE_EXCLUDES(m_mutex) {
VerilatedLockGuard lock{m_mutex};
m_mapResolved.clear();
}
};
// Only public_flat_rw has the sensitity tree

View File

@ -63,7 +63,9 @@ public:
void putsQuoted(const string& str) { ofp()->putsQuoted(str); }
void ensureNewLine() { ofp()->ensureNewLine(); }
bool optSystemC() { return v3Global.opt.systemC(); }
static string protect(const string& name) { return VIdProtect::protectIf(name, true); }
static string protect(const string& name) VL_MT_SAFE {
return VIdProtect::protectIf(name, true);
}
static string protectIf(const string& name, bool doIt) {
return VIdProtect::protectIf(name, doIt);
}
@ -84,7 +86,7 @@ public:
return symClassName() + "* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;\n";
}
static string funcNameProtect(const AstCFunc* nodep, const AstNodeModule* modp = nullptr);
static string prefixNameProtect(const AstNode* nodep) { // C++ name with prefix
static string prefixNameProtect(const AstNode* nodep) VL_MT_SAFE { // C++ name with prefix
return v3Global.opt.modPrefix() + "_" + protect(nodep->name());
}
static string topClassName() VL_MT_SAFE { // Return name of top wrapper module

View File

@ -108,7 +108,8 @@ class V3FileDependImp final {
};
// MEMBERS
std::set<string> m_filenameSet; // Files generated (elim duplicates)
VerilatedMutex m_mutex; // Protects members
std::set<string> m_filenameSet VL_GUARDED_BY(m_mutex); // Files generated (elim duplicates)
std::set<DependFile> m_filenameList; // Files sourced/generated
static string stripQuotes(const string& in) {
@ -121,7 +122,8 @@ class V3FileDependImp final {
public:
// ACCESSOR METHODS
void addSrcDepend(const string& filename) {
void addSrcDepend(const string& filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
const VerilatedLockGuard lock{m_mutex};
const auto itFoundPair = m_filenameSet.insert(filename);
if (itFoundPair.second) {
DependFile df{filename, false};
@ -129,7 +131,8 @@ public:
m_filenameList.insert(df);
}
}
void addTgtDepend(const string& filename) {
void addTgtDepend(const string& filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
const VerilatedLockGuard lock{m_mutex};
const auto itFoundPair = m_filenameSet.insert(filename);
if (itFoundPair.second) m_filenameList.insert(DependFile{filename, true});
}
@ -297,8 +300,8 @@ bool V3FileDependImp::checkTimes(const string& filename, const string& cmdlineIn
//######################################################################
// V3File
void V3File::addSrcDepend(const string& filename) { dependImp.addSrcDepend(filename); }
void V3File::addTgtDepend(const string& filename) { dependImp.addTgtDepend(filename); }
void V3File::addSrcDepend(const string& filename) VL_MT_SAFE { dependImp.addSrcDepend(filename); }
void V3File::addTgtDepend(const string& filename) VL_MT_SAFE { dependImp.addTgtDepend(filename); }
void V3File::writeDepend(const string& filename) { dependImp.writeDepend(filename); }
std::vector<string> V3File::getAllDeps() { return dependImp.getAllDeps(); }
void V3File::writeTimes(const string& filename, const string& cmdlineIn) {
@ -954,12 +957,13 @@ void V3OutCFile::putsGuard() {
class VIdProtectImp final {
// MEMBERS
VerilatedMutex m_mutex; // Protects members
std::map<const std::string, std::string> m_nameMap; // Map of old name into new name
std::unordered_set<std::string> m_newIdSet; // Which new names exist
std::unordered_set<std::string> m_newIdSet VL_GUARDED_BY(m_mutex); // Which new names exist
protected:
// CONSTRUCTORS
friend class VIdProtect;
static VIdProtectImp& singleton() {
static VIdProtectImp& singleton() VL_MT_SAFE {
static VIdProtectImp s;
return s;
}
@ -973,8 +977,9 @@ public:
}
~VIdProtectImp() = default;
// METHODS
string passthru(const string& old) {
string passthru(const string& old) VL_MT_SAFE_EXCLUDES(m_mutex) {
if (!v3Global.opt.protectIds()) return old;
const VerilatedLockGuard lock{m_mutex};
const auto it = m_nameMap.find(old);
if (it != m_nameMap.end()) {
// No way to go back and correct the older crypt name
@ -986,8 +991,9 @@ public:
}
return old;
}
string protectIf(const string& old, bool doIt) {
string protectIf(const string& old, bool doIt) VL_MT_SAFE_EXCLUDES(m_mutex) {
if (!v3Global.opt.protectIds() || old.empty() || !doIt) return old;
const VerilatedLockGuard lock{m_mutex};
const auto it = m_nameMap.find(old);
if (it != m_nameMap.end()) {
return it->second;
@ -1017,7 +1023,7 @@ public:
return out;
}
}
string protectWordsIf(const string& old, bool doIt) {
string protectWordsIf(const string& old, bool doIt) VL_MT_SAFE {
// Split at " " (for traces), "." (for scopes), "->", "(", "&", ")" (for self pointers)
if (!(doIt && v3Global.opt.protectIds())) return old;
string out;
@ -1056,7 +1062,7 @@ public:
private:
void trySep(const string& old, string::size_type start, const string& trySep,
string::size_type& posr, string& separatorr) {
string::size_type& posr, string& separatorr) VL_PURE {
const string::size_type trypos = old.find(trySep, start);
if (trypos != string::npos) {
if (posr == string::npos || (posr > trypos)) {
@ -1067,10 +1073,10 @@ private:
}
};
string VIdProtect::protectIf(const string& old, bool doIt) {
string VIdProtect::protectIf(const string& old, bool doIt) VL_MT_SAFE {
return VIdProtectImp::singleton().protectIf(old, doIt);
}
string VIdProtect::protectWordsIf(const string& old, bool doIt) {
string VIdProtect::protectWordsIf(const string& old, bool doIt) VL_MT_SAFE {
return VIdProtectImp::singleton().protectWordsIf(old, doIt);
}
void VIdProtect::writeMapFile(const string& filename) {

View File

@ -61,8 +61,8 @@ public:
}
// Dependencies
static void addSrcDepend(const string& filename);
static void addTgtDepend(const string& filename);
static void addSrcDepend(const string& filename) VL_MT_SAFE;
static void addTgtDepend(const string& filename) VL_MT_SAFE;
static void writeDepend(const string& filename);
static std::vector<string> getAllDeps();
static void writeTimes(const string& filename, const string& cmdlineIn);
@ -318,10 +318,10 @@ class VIdProtect final {
public:
// METHODS
// Rename to a new encoded string (unless earlier passthru'ed)
static string protect(const string& old) { return protectIf(old, true); }
static string protectIf(const string& old, bool doIt = true);
static string protect(const string& old) VL_MT_SAFE { return protectIf(old, true); }
static string protectIf(const string& old, bool doIt = true) VL_MT_SAFE;
// Rename words to a new encoded string
static string protectWordsIf(const string& old, bool doIt = true);
static string protectWordsIf(const string& old, bool doIt = true) VL_MT_SAFE;
// Write map of renames to output file
static void writeMapFile(const string& filename);
};

View File

@ -87,7 +87,9 @@ void FileLineSingleton::fileNameNumMapDumpXml(std::ostream& os) {
os << "</files>\n";
}
FileLineSingleton::msgEnSetIdx_t FileLineSingleton::addMsgEnBitSet(const MsgEnBitSet& bitSet) {
FileLineSingleton::msgEnSetIdx_t FileLineSingleton::addMsgEnBitSet(const MsgEnBitSet& bitSet)
VL_MT_SAFE_EXCLUDES(m_mutex) {
VerilatedLockGuard lock{m_mutex};
const auto pair = m_internedMsgEnIdxs.emplace(bitSet, 0);
msgEnSetIdx_t& idx = pair.first->second;
if (pair.second) {
@ -100,7 +102,7 @@ FileLineSingleton::msgEnSetIdx_t FileLineSingleton::addMsgEnBitSet(const MsgEnBi
return idx;
}
FileLineSingleton::msgEnSetIdx_t FileLineSingleton::defaultMsgEnIndex() {
FileLineSingleton::msgEnSetIdx_t FileLineSingleton::defaultMsgEnIndex() VL_MT_SAFE {
MsgEnBitSet msgEnBitSet;
for (int i = V3ErrorCode::EC_MIN; i < V3ErrorCode::_ENUM_MAX; ++i) {
msgEnBitSet.set(i, !V3ErrorCode{i}.defaultsOff());

View File

@ -20,6 +20,8 @@
#include "config_build.h"
#include "verilatedos.h"
#include "verilated_threads.h"
#include "V3Error.h"
#include "V3LangCode.h"
@ -50,12 +52,13 @@ class FileLineSingleton final {
using MsgEnBitSet = std::bitset<V3ErrorCode::_ENUM_MAX>;
// MEMBERS
VerilatedMutex m_mutex; // protects members
std::map<const std::string, fileNameIdx_t> m_namemap; // filenameno for each filename
std::deque<string> m_names; // filename text for each filenameno
std::deque<V3LangCode> m_languages; // language for each filenameno
// Map from flag set to the index in m_internedMsgEns for interning
std::unordered_map<MsgEnBitSet, msgEnSetIdx_t> m_internedMsgEnIdxs;
std::unordered_map<MsgEnBitSet, msgEnSetIdx_t> m_internedMsgEnIdxs VL_GUARDED_BY(m_mutex);
// Interned message enablement flag sets
std::vector<MsgEnBitSet> m_internedMsgEns;
@ -78,9 +81,9 @@ class FileLineSingleton final {
static string filenameLetters(fileNameIdx_t fileno) VL_PURE;
// Add given bitset to the interned bitsets, return interned index
msgEnSetIdx_t addMsgEnBitSet(const MsgEnBitSet& bitSet);
msgEnSetIdx_t addMsgEnBitSet(const MsgEnBitSet& bitSet) VL_MT_SAFE_EXCLUDES(m_mutex);
// Add index of default bitset
msgEnSetIdx_t defaultMsgEnIndex();
msgEnSetIdx_t defaultMsgEnIndex() VL_MT_SAFE;
// Set bitIdx to value in bitset at interned index setIdx, return interned index of result
msgEnSetIdx_t msgEnSetBit(msgEnSetIdx_t setIdx, size_t bitIdx, bool value);
// Return index to intersection set

View File

@ -134,7 +134,9 @@ public:
~GateVarVertex() override = default;
// ACCESSORS
AstVarScope* varScp() const { return m_varScp; }
string name() const override { return (cvtToHex(m_varScp) + " " + varScp()->name()); }
string name() const override VL_MT_STABLE {
return (cvtToHex(m_varScp) + " " + varScp()->name());
}
string dotColor() const override { return "blue"; }
bool isTop() const { return m_isTop; }
void setIsTop() { m_isTop = true; }
@ -174,7 +176,9 @@ public:
, m_slow{slow} {}
~GateLogicVertex() override = default;
// ACCESSORS
string name() const override { return (cvtToHex(m_nodep) + "@" + scopep()->prettyName()); }
string name() const override VL_MT_STABLE {
return (cvtToHex(m_nodep) + "@" + scopep()->prettyName());
}
string dotColor() const override { return "purple"; }
FileLine* fileline() const override { return nodep()->fileline(); }
AstNode* nodep() const { return m_nodep; }

View File

@ -98,7 +98,7 @@ class V3Global final {
VWidthMinUsage m_widthMinUsage
= VWidthMinUsage::LINT_WIDTH; // What AstNode::widthMin() is used for
int m_debugFileNumber = 0; // Number to append to debug files created
std::atomic_int m_debugFileNumber{0}; // Number to append to debug files created
bool m_assertDTypesResolved = false; // Tree should have dtypep()'s
bool m_assertScoped = false; // Tree is scoped
bool m_constRemoveXs = false; // Const needs to strip any Xs
@ -143,7 +143,7 @@ public:
void widthMinUsage(const VWidthMinUsage& flag) { m_widthMinUsage = flag; }
bool constRemoveXs() const { return m_constRemoveXs; }
void constRemoveXs(bool flag) { m_constRemoveXs = flag; }
string debugFilename(const string& nameComment, int newNumber = 0) VL_MT_SAFE;
string debugFilename(const string& nameComment, int newNumber = 0);
static string digitsFilename(int number);
bool needTraceDumper() const { return m_needTraceDumper; }
void needTraceDumper(bool flag) { m_needTraceDumper = flag; }

View File

@ -60,7 +60,7 @@ public:
, m_name{name} {}
~V3GraphTestVertex() override = default;
// ACCESSORS
string name() const override { return m_name; }
string name() const override VL_MT_STABLE { return m_name; }
};
class V3GraphTestVarVertex final : public V3GraphTestVertex {

View File

@ -59,8 +59,8 @@ public:
: V3GraphVertex{graphp}
, m_modp{modp} {}
~LinkCellsVertex() override = default;
AstNodeModule* modp() const { return m_modp; }
string name() const override { return modp()->name(); }
AstNodeModule* modp() const VL_MT_STABLE { return m_modp; }
string name() const override VL_MT_STABLE { return modp()->name(); }
FileLine* fileline() const override { return modp()->fileline(); }
// Recursive modules get space for maximum recursion
uint32_t rankAdder() const override {
@ -73,7 +73,7 @@ public:
explicit LibraryVertex(V3Graph* graphp)
: V3GraphVertex{graphp} {}
~LibraryVertex() override = default;
string name() const override { return "*LIBRARY*"; }
string name() const override VL_MT_STABLE { return "*LIBRARY*"; }
};
void LinkCellsGraph::loopsMessageCb(V3GraphVertex* vertexp) {

View File

@ -498,7 +498,7 @@ V3Number& V3Number::setMask(int nbits) {
//======================================================================
// ACCESSORS - as strings
string V3Number::ascii(bool prefixed, bool cleanVerilog) const {
string V3Number::ascii(bool prefixed, bool cleanVerilog) const VL_MT_SAFE {
std::ostringstream out;
if (is1Step()) {
@ -1050,7 +1050,7 @@ bool V3Number::isEqAllOnes(int optwidth) const {
}
return true;
}
bool V3Number::isFourState() const {
bool V3Number::isFourState() const VL_MT_SAFE {
if (isDouble() || isString()) return false;
for (int i = 0; i < words(); ++i) {
if (m_data.num()[i].m_valueX) return true;

View File

@ -583,7 +583,7 @@ public:
V3Number& setMask(int nbits); // IE if nbits=1, then 0b1, if 2->0b11, if 3->0b111 etc
// ACCESSORS
string ascii(bool prefixed = true, bool cleanVerilog = false) const;
string ascii(bool prefixed = true, bool cleanVerilog = false) const VL_MT_SAFE;
string displayed(AstNode* nodep, const string& vformat) const VL_MT_SAFE;
static bool displayedFmtLegal(char format, bool isScan); // Is this a valid format letter?
int width() const VL_MT_SAFE { return m_data.width(); }
@ -615,7 +615,7 @@ public:
bool isNegative() const { return !isString() && bitIs1(width() - 1); }
bool is1Step() const VL_MT_SAFE { return m_data.m_is1Step; }
bool isNull() const VL_MT_SAFE { return m_data.m_isNull; }
bool isFourState() const;
bool isFourState() const VL_MT_SAFE;
bool hasZ() const {
if (isString()) return false;
for (int i = 0; i < words(); i++) {

View File

@ -880,7 +880,9 @@ string V3Options::version() VL_PURE {
return ver;
}
string V3Options::protectKeyDefaulted() {
string V3Options::protectKeyDefaulted() VL_MT_SAFE {
static VerilatedMutex mutex;
const VerilatedLockGuard lock{mutex};
if (m_protectKey.empty()) {
// Create a key with a human-readable symbol-like name.
// This conversion drops ~2 bits of entropy out of 256, shouldn't matter.

View File

@ -573,7 +573,7 @@ public:
string prefix() const VL_MT_SAFE { return m_prefix; }
// Not just called protectKey() to avoid bugs of not using protectKeyDefaulted()
bool protectKeyProvided() const { return !m_protectKey.empty(); }
string protectKeyDefaulted(); // Set default key if not set by user
string protectKeyDefaulted() VL_MT_SAFE; // Set default key if not set by user
string topModule() const { return m_topModule; }
string unusedRegexp() const { return m_unusedRegexp; }
string waiverOutput() const { return m_waiverOutput; }

View File

@ -159,7 +159,7 @@ public:
AstSenTree* hybridp() const { return m_hybridp; }
// LCOV_EXCL_START // Debug code
string name() const override {
string name() const override VL_MT_STABLE {
return (cvtToHex(m_nodep) + "\\n " + cvtToStr(nodep()->typeName()));
}
string dotShape() const override { return VN_IS(m_nodep, Active) ? "doubleoctagon" : "rect"; }
@ -182,7 +182,7 @@ public:
// LCOV_EXCL_START // Debug code
string dotShape() const override final { return "ellipse"; }
virtual string nameSuffix() const = 0;
string name() const override final {
string name() const override final VL_MT_STABLE {
return cvtToHex(m_vscp) + " " + nameSuffix() + "\\n " + m_vscp->name();
}
// LCOV_EXCL_STOP

View File

@ -64,7 +64,7 @@ public:
}
}
string name() const override {
string name() const override VL_MT_STABLE {
string nm;
if (VL_UNCOVERABLE(!logicp())) { // Avoid crash when debugging
nm = "nul"; // LCOV_EXCL_LINE

View File

@ -28,6 +28,8 @@
#include "config_build.h"
#include "verilatedos.h"
#include "verilated_threads.h"
// Limited V3 headers here - this is a base class for Vlc etc
#include "V3Os.h"
#include "V3String.h"
@ -286,7 +288,7 @@ uint64_t V3Os::rand64(std::array<uint64_t, 2>& stater) {
return result;
}
string V3Os::trueRandom(size_t size) {
string V3Os::trueRandom(size_t size) VL_MT_SAFE {
string result(size, '\xFF');
char* const data = const_cast<char*>(result.data());
// Note: std::string.data() returns a non-const Char* from C++17 onwards.

View File

@ -59,7 +59,7 @@ public:
// METHODS (random)
static uint64_t rand64(std::array<uint64_t, 2>& stater);
static string trueRandom(size_t size);
static string trueRandom(size_t size) VL_MT_SAFE;
// METHODS (time & performance)
static void u_sleep(int64_t usec); ///< Sleep for a given number of microseconds.

View File

@ -321,7 +321,7 @@ public:
void checkRelativesCp(GraphWay way) const;
string name() const override {
string name() const override VL_MT_STABLE {
// Display forward and reverse critical path costs. This gives a quick
// read on whether graph partitioning looks reasonable or bad.
std::ostringstream out;

View File

@ -85,7 +85,7 @@ public:
// If this MTask maps to a C function, this should be the name
return std::string{"__Vmtask"} + "__" + cvtToStr(m_id);
}
string name() const override { return std::string{"mt"} + cvtToStr(id()); }
string name() const override VL_MT_STABLE { return std::string{"mt"} + cvtToStr(id()); }
string hashName() const { return m_hashName; }
void hashName(const string& name) { m_hashName = name; }
void dump(std::ostream& str) const {

View File

@ -76,7 +76,7 @@ public:
AstScope* scopep() const { return m_scopep; }
// LCOV_EXCL_START // Debug code
string name() const override { return m_logicp->fileline()->ascii(); };
string name() const override VL_MT_STABLE { return m_logicp->fileline()->ascii(); };
string dotShape() const override { return "rectangle2"; }
// LCOV_EXCL_STOP
};
@ -93,7 +93,7 @@ public:
V3GraphVertex* clone(V3Graph* graphp) const override { return new VarVertex{graphp, vscp()}; }
// LCOV_EXCL_START // Debug code
string name() const override { return m_vscp->name(); }
string name() const override VL_MT_STABLE { return m_vscp->name(); }
string dotShape() const override { return "ellipse"; }
string dotColor() const override { return "blue"; }
// LCOV_EXCL_STOP

View File

@ -89,7 +89,7 @@ public:
AstNode* logicp() const { return m_logicp; }
// LCOV_EXCL_START // Debug code
string name() const override {
string name() const override VL_MT_STABLE {
return m_logicp->typeName() + ("\n" + m_logicp->fileline()->ascii());
};
string dotShape() const override { return "rectangle"; }
@ -105,7 +105,7 @@ public:
, m_vscp{vscp} {}
// LCOV_EXCL_START // Debug code
string name() const override { return m_vscp->name(); }
string name() const override VL_MT_STABLE { return m_vscp->name(); }
string dotShape() const override {
return m_vscp->scopep()->isTop() && m_vscp->varp()->isNonOutput() ? "invhouse" : "ellipse";
}

View File

@ -109,7 +109,7 @@ public:
RegionFlags assignedRegion() const { return m_assignedRegion; }
// For graph dumping
string name() const override { return m_logicp->fileline()->ascii(); };
string name() const override VL_MT_STABLE { return m_logicp->fileline()->ascii(); };
string dotShape() const override { return "rectangle"; }
};
@ -134,7 +134,7 @@ public:
AstScope* scopep() const { return m_vscp->scopep(); }
// For graph dumping
string name() const override { return m_vscp->name(); }
string name() const override VL_MT_STABLE { return m_vscp->name(); }
string dotShape() const override { return varp()->isPrimaryInish() ? "invhouse" : "ellipse"; }
};

View File

@ -109,7 +109,9 @@ protected:
// ACCESSORS
// Do not make accessor for nodep(), It may change due to
// reordering a lower block, but we don't repair it
string name() const override { return cvtToHex(m_nodep) + ' ' + m_nodep->prettyTypeName(); }
string name() const override VL_MT_STABLE {
return cvtToHex(m_nodep) + ' ' + m_nodep->prettyTypeName();
}
FileLine* fileline() const override { return nodep()->fileline(); }
public:
@ -121,7 +123,7 @@ public:
explicit SplitPliVertex(V3Graph* graphp, AstNode* nodep)
: SplitNodeVertex{graphp, nodep} {}
~SplitPliVertex() override = default;
string name() const override { return "*PLI*"; }
string name() const override VL_MT_STABLE { return "*PLI*"; }
string dotColor() const override { return "green"; }
};
@ -146,7 +148,7 @@ public:
SplitVarPostVertex(V3Graph* graphp, AstNode* nodep)
: SplitNodeVertex{graphp, nodep} {}
~SplitVarPostVertex() override = default;
string name() const override { return string("POST ") + SplitNodeVertex::name(); }
string name() const override VL_MT_STABLE { return string("POST ") + SplitNodeVertex::name(); }
string dotColor() const override { return "CadetBlue"; }
};

View File

@ -67,8 +67,8 @@ public:
: TaskBaseVertex{graphp}
, m_nodep{nodep} {}
~TaskFTaskVertex() override = default;
AstNodeFTask* nodep() const { return m_nodep; }
string name() const override { return nodep()->name(); }
AstNodeFTask* nodep() const VL_MT_STABLE { return m_nodep; }
string name() const override VL_MT_STABLE { return nodep()->name(); }
string dotColor() const override { return pure() ? "black" : "red"; }
AstCFunc* cFuncp() const { return m_cFuncp; }
void cFuncp(AstCFunc* nodep) { m_cFuncp = nodep; }
@ -80,7 +80,7 @@ public:
explicit TaskCodeVertex(V3Graph* graphp)
: TaskBaseVertex{graphp} {}
~TaskCodeVertex() override = default;
string name() const override { return "*CODE*"; }
string name() const override VL_MT_STABLE { return "*CODE*"; }
string dotColor() const override { return "green"; }
};

View File

@ -67,7 +67,7 @@ private:
class DependencyVertex final : public V3GraphVertex {
AstNode* const m_nodep; // AST node represented by this graph vertex
// ACCESSORS
string name() const override {
string name() const override VL_MT_STABLE {
return cvtToHex(nodep()) + ' ' + nodep()->prettyTypeName();
}
FileLine* fileline() const override { return nodep()->fileline(); }

View File

@ -154,7 +154,7 @@ public:
// ACCESSORS
AstNode* nodep() const { return m_nodep; }
const AstVar* varp() const { return VN_CAST(nodep(), Var); }
string name() const override {
string name() const override VL_MT_STABLE {
return ((isTristate() ? "tri\\n"
: feedsTri() ? "feed\\n"
: "-\\n")

View File

@ -23,8 +23,9 @@
#include <memory>
#include <sstream>
void V3Waiver::addEntry(V3ErrorCode errorCode, const std::string& filename,
const std::string& str) {
void V3Waiver::addEntry(V3ErrorCode errorCode, const std::string& filename, const std::string& str)
VL_MT_SAFE_EXCLUDES(s_mutex) {
const VerilatedLockGuard lock{s_mutex};
std::stringstream entry;
const size_t pos = str.find('\n');
entry << "lint_off -rule " << errorCode.ascii() << " -file \"*" << filename << "\" -match \""
@ -34,7 +35,7 @@ void V3Waiver::addEntry(V3ErrorCode errorCode, const std::string& filename,
s_waiverList.push_back(entry.str());
}
void V3Waiver::write(const std::string& filename) {
void V3Waiver::write(const std::string& filename) VL_MT_SAFE_EXCLUDES(s_mutex) {
const std::unique_ptr<std::ofstream> ofp{V3File::new_ofstream(filename)};
if (ofp->fail()) v3fatal("Can't write " << filename);
@ -48,9 +49,12 @@ void V3Waiver::write(const std::string& filename) {
*ofp << "// 2. Keep the waiver permanently if you are sure this is okay\n";
*ofp << "// 3. Keep the waiver temporarily to suppress the output\n\n";
const VerilatedLockGuard lock{s_mutex};
if (s_waiverList.empty()) *ofp << "// No waivers needed - great!\n";
for (const auto& i : s_waiverList) *ofp << "// " << i << "\n\n";
}
VerilatedMutex V3Waiver::s_mutex;
V3Waiver::WaiverList V3Waiver::s_waiverList;

View File

@ -17,6 +17,8 @@
#ifndef VERILATOR_V3WAIVER_H_
#define VERILATOR_V3WAIVER_H_
#include "verilated_threads.h"
#include "V3Error.h"
#include <string>
@ -25,11 +27,13 @@
class V3Waiver final {
// TYPES
using WaiverList = std::vector<std::string>;
static WaiverList s_waiverList;
static VerilatedMutex s_mutex; // Protect members
static WaiverList s_waiverList VL_GUARDED_BY(s_mutex);
public:
static void addEntry(V3ErrorCode errorCode, const string& filename, const std::string& str);
static void write(const std::string& filename);
static void addEntry(V3ErrorCode errorCode, const string& filename, const std::string& str)
VL_MT_SAFE_EXCLUDES(s_mutex);
static void write(const std::string& filename) VL_MT_SAFE_EXCLUDES(s_mutex);
};
#endif // Guard