Internals: Fix some 'p' names, and make new base class for VlDeleter. No functional change intended.

This commit is contained in:
Wilson Snyder 2022-11-13 17:40:50 -05:00
parent c6ecd60993
commit 8c6d1e53ca
6 changed files with 48 additions and 42 deletions

View File

@ -3102,7 +3102,7 @@ void VlDeleter::deleteAll() {
VerilatedLockGuard deleteLock{m_deleteMutex};
std::swap(m_newGarbage, m_toDelete);
lock.unlock(); // So destuctors can enqueue new objects
for (VlClass* const objp : m_toDelete) delete objp;
for (VlDeletable* const objp : m_toDelete) delete objp;
m_toDelete.clear();
}
}

View File

@ -95,7 +95,7 @@ VerilatedFst::VerilatedFst(void* /*fst*/) {}
VerilatedFst::~VerilatedFst() {
if (m_fst) fstWriterClose(m_fst);
if (m_symbolp) VL_DO_CLEAR(delete[] m_symbolp, m_symbolp = nullptr);
if (m_strbuf) VL_DO_CLEAR(delete[] m_strbuf, m_strbuf = nullptr);
if (m_strbufp) VL_DO_CLEAR(delete[] m_strbufp, m_strbufp = nullptr);
}
void VerilatedFst::open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
@ -125,7 +125,7 @@ void VerilatedFst::open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
m_code2symbol.clear();
// Allocate string buffer for arrays
if (!m_strbuf) m_strbuf = new char[maxBits() + 32];
if (!m_strbufp) m_strbufp = new char[maxBits() + 32];
}
void VerilatedFst::close() VL_MT_SAFE_EXCLUDES(m_mutex) {
@ -320,7 +320,7 @@ void VerilatedFstBuffer::emitQData(uint32_t code, QData newval, int bits) {
VL_ATTR_ALWINLINE
void VerilatedFstBuffer::emitWData(uint32_t code, const WData* newvalp, int bits) {
int words = VL_WORDS_I(bits);
char* wp = m_strbuf;
char* wp = m_strbufp;
// Convert the most significant word
const int bitsInMSW = VL_BITBIT_E(bits) ? VL_BITBIT_E(bits) : VL_EDATASIZE;
cvtEDataToStr(wp, newvalp[--words] << (VL_EDATASIZE - bitsInMSW));
@ -330,7 +330,7 @@ void VerilatedFstBuffer::emitWData(uint32_t code, const WData* newvalp, int bits
cvtEDataToStr(wp, newvalp[--words]);
wp += VL_EDATASIZE;
}
fstWriterEmitValueChange(m_fst, m_symbolp[code], m_strbuf);
fstWriterEmitValueChange(m_fst, m_symbolp[code], m_strbufp);
}
VL_ATTR_ALWINLINE

View File

@ -53,7 +53,7 @@ private:
std::map<int, fstEnumHandle> m_local2fstdtype;
std::list<std::string> m_curScope;
fstHandle* m_symbolp = nullptr; // same as m_code2symbol, but as an array
char* m_strbuf = nullptr; // String buffer long enough to hold maxBits() chars
char* m_strbufp = nullptr; // String buffer long enough to hold maxBits() chars
bool m_useFstWriterThread = false; // Whether to use the separate FST writer thread
@ -149,7 +149,7 @@ class VerilatedFstBuffer VL_NOT_FINAL {
// code to fstHande map, as an array
const fstHandle* const m_symbolp = m_owner.m_symbolp;
// String buffer long enough to hold maxBits() chars
char* const m_strbuf = m_owner.m_strbuf;
char* const m_strbufp = m_owner.m_strbufp;
// CONSTRUCTOR
explicit VerilatedFstBuffer(VerilatedFst& owner)

View File

@ -444,16 +444,16 @@ static inline void VL_ASSIGNBIT_WO(int bit, WDataOutP owp) VL_MT_SAFE {
{ \
const int words = VL_WORDS_I(obits); \
sc_biguint<(obits)> _butemp = (svar).read(); \
uint32_t* chunk = _butemp.get_raw(); \
uint32_t* chunkp = _butemp.get_raw(); \
int32_t lsb = 0; \
while (lsb < obits - BITS_PER_DIGIT) { \
const uint32_t data = *chunk; \
++chunk; \
const uint32_t data = *chunkp; \
++chunkp; \
_vl_insert_WI(owp.data(), data, lsb + BITS_PER_DIGIT - 1, lsb); \
lsb += BITS_PER_DIGIT; \
} \
if (lsb < obits) { \
const uint32_t msb_data = *chunk; \
const uint32_t msb_data = *chunkp; \
_vl_insert_WI(owp.data(), msb_data, obits - 1, lsb); \
} \
(owp)[words - 1] &= VL_MASK_E(obits); \
@ -500,18 +500,18 @@ static inline void VL_ASSIGNBIT_WO(int bit, WDataOutP owp) VL_MT_SAFE {
{ \
sc_biguint<(obits)> _butemp; \
int32_t lsb = 0; \
uint32_t* chunk = _butemp.get_raw(); \
uint32_t* chunkp = _butemp.get_raw(); \
while (lsb + VL_SC_BITS_PER_DIGIT < (obits)) { \
static_assert(std::is_same<IData, EData>::value, "IData and EData missmatch"); \
const uint32_t data = VL_SEL_IWII(lsb + VL_SC_BITS_PER_DIGIT + 1, (rwp).data(), lsb, \
VL_SC_BITS_PER_DIGIT); \
*chunk = data & VL_MASK_E(VL_SC_BITS_PER_DIGIT); \
++chunk; \
*chunkp = data & VL_MASK_E(VL_SC_BITS_PER_DIGIT); \
++chunkp; \
lsb += VL_SC_BITS_PER_DIGIT; \
} \
if (lsb < (obits)) { \
const uint32_t msb_data = VL_SEL_IWII((obits) + 1, (rwp).data(), lsb, (obits)-lsb); \
*chunk = msb_data & VL_MASK_E((obits)-lsb); \
*chunkp = msb_data & VL_MASK_E((obits)-lsb); \
} \
(svar).write(_butemp); \
}

View File

@ -1004,7 +1004,14 @@ std::string VL_TO_STRING(const VlUnpacked<T_Value, T_Depth>& obj) {
return obj.to_string();
}
class VlClass; // See below
//===================================================================
// Object that VlDeleter is capable of deleting
class VlDeletable VL_NOT_FINAL {
public:
VlDeletable() = default;
virtual ~VlDeletable() = default;
};
//===================================================================
// Class providing delayed deletion of garbage objects. Objects get deleted only when 'deleteAll()'
@ -1013,9 +1020,9 @@ class VlClass; // See below
class VlDeleter final {
// MEMBERS
// Queue of new objects that should be deleted
std::vector<VlClass*> m_newGarbage VL_GUARDED_BY(m_mutex);
std::vector<VlDeletable*> m_newGarbage VL_GUARDED_BY(m_mutex);
// Queue of objects currently being deleted (only for deleteAll())
std::vector<VlClass*> m_toDelete VL_GUARDED_BY(m_deleteMutex);
std::vector<VlDeletable*> m_toDelete VL_GUARDED_BY(m_deleteMutex);
mutable VerilatedMutex m_mutex; // Mutex protecting the 'new garbage' queue
mutable VerilatedMutex m_deleteMutex; // Mutex protecting the delete queue
@ -1030,7 +1037,7 @@ private:
public:
// METHODS
// Adds a new object to the 'new garbage' queue.
void put(VlClass* const objp) VL_MT_SAFE {
void put(VlDeletable* const objp) VL_MT_SAFE {
const VerilatedLockGuard lock{m_mutex};
m_newGarbage.push_back(objp);
}
@ -1042,17 +1049,16 @@ public:
//===================================================================
// Base class for all verilated classes. Includes a reference counter, and a pointer to the deleter
// object that should destroy it after the counter reaches 0. This allows for easy construction of
// VlClassRefs from 'this'. Also declares a virtual constructor, so that the object can be deleted
// using a base pointer.
// VlClassRefs from 'this'.
class VlClass VL_NOT_FINAL {
class VlClass VL_NOT_FINAL : public VlDeletable {
// TYPES
template <typename T_Class>
friend class VlClassRef; // Needed for access to the ref counter and deleter
// MEMBERS
std::atomic<size_t> m_counter{0}; // Reference count for this object
VlDeleter* m_deleter = nullptr; // The deleter that will delete this object
VlDeleter* m_deleterp = nullptr; // The deleter that will delete this object
// METHODS
// Atomically increments the reference counter
@ -1060,14 +1066,14 @@ class VlClass VL_NOT_FINAL {
// Atomically decrements the reference counter. Assuming VlClassRef semantics are sound, it
// should never get called at m_counter == 0.
void refCountDec() VL_MT_SAFE {
if (!--m_counter) m_deleter->put(this);
if (!--m_counter) m_deleterp->put(this);
}
public:
// CONSTRUCTORS
VlClass() = default;
VlClass(const VlClass& copied) {}
virtual ~VlClass() {}
~VlClass() override = default;
};
//===================================================================
@ -1110,7 +1116,7 @@ public:
template <typename... T_Args>
VlClassRef(VlDeleter& deleter, T_Args&&... args)
: m_objp{new T_Class{std::forward<T_Args>(args)...}} {
m_objp->m_deleter = &deleter;
m_objp->m_deleterp = &deleter;
refCountInc();
}
// Explicit to avoid implicit conversion from 0

View File

@ -71,7 +71,7 @@ class VerilatedVpio VL_NOT_FINAL {
// MEM MANGLEMENT
// Internal note: Globals may multi-construct, see verilated.cpp top.
static thread_local uint8_t* t_freeHead;
static thread_local uint8_t* t_freeHeadp;
public:
// CONSTRUCTORS
@ -85,9 +85,9 @@ public:
static constexpr size_t CHUNK_SIZE = 96;
if (VL_UNCOVERABLE(size > CHUNK_SIZE))
VL_FATAL_MT(__FILE__, __LINE__, "", "increase CHUNK_SIZE");
if (VL_LIKELY(t_freeHead)) {
uint8_t* const newp = t_freeHead;
t_freeHead = *(reinterpret_cast<uint8_t**>(newp));
if (VL_LIKELY(t_freeHeadp)) {
uint8_t* const newp = t_freeHeadp;
t_freeHeadp = *(reinterpret_cast<uint8_t**>(newp));
*(reinterpret_cast<uint32_t*>(newp)) = activeMagic();
return newp + 8;
}
@ -106,8 +106,8 @@ public:
#ifdef VL_VPI_IMMEDIATE_FREE // Define to aid in finding leaky handles
::operator delete(oldp);
#else
*(reinterpret_cast<void**>(oldp)) = t_freeHead;
t_freeHead = oldp;
*(reinterpret_cast<void**>(oldp)) = t_freeHeadp;
t_freeHeadp = oldp;
#endif
}
// MEMBERS
@ -225,28 +225,28 @@ public:
};
class VerilatedVpioRange final : public VerilatedVpio {
const VerilatedRange* const m_range;
const VerilatedRange* const m_rangep;
public:
explicit VerilatedVpioRange(const VerilatedRange* range)
: m_range{range} {}
explicit VerilatedVpioRange(const VerilatedRange* rangep)
: m_rangep{rangep} {}
~VerilatedVpioRange() override = default;
static VerilatedVpioRange* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioRange*>(reinterpret_cast<VerilatedVpio*>(h));
}
uint32_t type() const override { return vpiRange; }
uint32_t size() const override { return m_range->elements(); }
const VerilatedRange* rangep() const override { return m_range; }
uint32_t size() const override { return m_rangep->elements(); }
const VerilatedRange* rangep() const override { return m_rangep; }
};
class VerilatedVpioRangeIter final : public VerilatedVpio {
// Only supports 1 dimension
const VerilatedRange* const m_range;
const VerilatedRange* const m_rangep;
bool m_done = false;
public:
explicit VerilatedVpioRangeIter(const VerilatedRange* range)
: m_range{range} {}
explicit VerilatedVpioRangeIter(const VerilatedRange* rangep)
: m_rangep{rangep} {}
~VerilatedVpioRangeIter() override = default;
static VerilatedVpioRangeIter* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioRangeIter*>(reinterpret_cast<VerilatedVpio*>(h));
@ -258,7 +258,7 @@ public:
return nullptr;
}
m_done = true;
return ((new VerilatedVpioRange{m_range})->castVpiHandle());
return ((new VerilatedVpioRange{m_rangep})->castVpiHandle());
}
};
@ -666,7 +666,7 @@ public:
// Statics
// Internal note: Globals may multi-construct, see verilated.cpp top.
thread_local uint8_t* VerilatedVpio::t_freeHead = nullptr;
thread_local uint8_t* VerilatedVpio::t_freeHeadp = nullptr;
//======================================================================
// VerilatedVpiError