mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Internals: Fix some 'p' names, and make new base class for VlDeleter. No functional change intended.
This commit is contained in:
parent
c6ecd60993
commit
8c6d1e53ca
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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); \
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user