[#74021] move activity accumulating code to its own class

This commit is contained in:
Mateusz Gancarz 2025-03-05 12:43:30 +01:00
parent b383f64cff
commit c71f5b42e3
2 changed files with 130 additions and 76 deletions

View File

@ -94,7 +94,9 @@ VerilatedSaifActivityBit& VerilatedSaifActivityVar::bit(const std::size_t index)
//============================================================================= //=============================================================================
// Opening/Closing // Opening/Closing
VerilatedSaif::VerilatedSaif(void* filep) {} VerilatedSaif::VerilatedSaif(void* filep) {
m_activityAccumulators.emplace_back();
}
void VerilatedSaif::open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) { void VerilatedSaif::open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
const VerilatedLockGuard lock{m_mutex}; const VerilatedLockGuard lock{m_mutex};
@ -178,14 +180,26 @@ void VerilatedSaif::closeInstanceScope() {
} }
void VerilatedSaif::printScopeActivities(const VerilatedSaifActivityScope& scope) { void VerilatedSaif::printScopeActivities(const VerilatedSaifActivityScope& scope) {
bool anyNetValid{false}; bool anyNetWritten{false};
for (const auto& childSignal : scope.childActivities()) {
const uint32_t code = childSignal.first; for (auto& accumulator : m_activityAccumulators) {
const char* const name = childSignal.second.c_str(); anyNetWritten |= printScopeActivitiesFromAccumulatorIfPresent(scope.path(), accumulator, anyNetWritten);
anyNetValid = printActivityStats(code, name, anyNetValid);
} }
if (anyNetValid) closeNetScope(); if (anyNetWritten) closeNetScope();
}
bool VerilatedSaif::printScopeActivitiesFromAccumulatorIfPresent(const std::string& absoluteScopePath, VerilatedSaifActivityAccumulator& accumulator, bool anyNetWritten) {
if (accumulator.m_scopeToActivities.count(absoluteScopePath) == 0) {
return false;
}
for (const auto& childSignal : accumulator.m_scopeToActivities.at(absoluteScopePath)) {
VerilatedSaifActivityVar& activityVariable = accumulator.m_activity.at(childSignal.first);
anyNetWritten = printActivityStats(activityVariable, childSignal.second.c_str(), anyNetWritten);
}
return anyNetWritten;
} }
void VerilatedSaif::openNetScope() { void VerilatedSaif::openNetScope() {
@ -200,9 +214,8 @@ void VerilatedSaif::closeNetScope() {
printStr(")\n"); printStr(")\n");
} }
bool VerilatedSaif::printActivityStats(const uint32_t activityCode, const char* activityName, bool VerilatedSaif::printActivityStats(VerilatedSaifActivityVar& activity, const char* activityName,
bool anyNetValid) { bool anyNetWritten) {
VerilatedSaifActivityVar& activity = m_activity.at(activityCode);
for (size_t i = 0; i < activity.width(); ++i) { for (size_t i = 0; i < activity.width(); ++i) {
VerilatedSaifActivityBit& bit = activity.bit(i); VerilatedSaifActivityBit& bit = activity.bit(i);
@ -213,9 +226,9 @@ bool VerilatedSaif::printActivityStats(const uint32_t activityCode, const char*
bit.aggregateVal(currentTime() - activity.lastUpdateTime(), bit.bitValue()); bit.aggregateVal(currentTime() - activity.lastUpdateTime(), bit.bitValue());
if (!anyNetValid) { if (!anyNetWritten) {
openNetScope(); openNetScope();
anyNetValid = true; anyNetWritten = true;
} }
printIndent(); printIndent();
@ -239,15 +252,14 @@ bool VerilatedSaif::printActivityStats(const uint32_t activityCode, const char*
activity.updateLastTime(currentTime()); activity.updateLastTime(currentTime());
return anyNetValid; return anyNetWritten;
} }
void VerilatedSaif::clearCurrentlyCollectedData() { void VerilatedSaif::clearCurrentlyCollectedData() {
m_currentScope = -1; m_currentScope = -1;
m_scopes.clear(); m_scopes.clear();
m_topScopes.clear(); m_topScopes.clear();
m_activity.clear(); m_activityAccumulators.clear();
m_activityArena.clear();
} }
void VerilatedSaif::printStr(const char* str) { ::write(m_filep, str, strlen(str)); } void VerilatedSaif::printStr(const char* str) { ::write(m_filep, str, strlen(str)); }
@ -287,7 +299,11 @@ void VerilatedSaif::pushPrefix(const std::string& name, VerilatedTracePrefixType
} else { } else {
m_topScopes.emplace_back(newScopeIndex); m_topScopes.emplace_back(newScopeIndex);
} }
m_scopes.emplace_back(lastWord(m_prefixStack.back().first + pname), m_currentScope);
std::string scopePath = m_prefixStack.back().first + pname;
std::string scopeName = lastWord(scopePath);
m_scopes.emplace_back(std::move(scopePath), std::move(scopeName), m_currentScope);
m_currentScope = newScopeIndex; m_currentScope = newScopeIndex;
} }
@ -310,15 +326,7 @@ void VerilatedSaif::popPrefix() {
m_prefixStack.pop_back(); m_prefixStack.pop_back();
} }
void VerilatedSaif::declare(const uint32_t code, const char* name, const char* wirep, void VerilatedSaifActivityAccumulator::declare(uint32_t code, const std::string& absoluteScopePath, std::string variableName, int bits, bool array, int arraynum) {
const bool array, const int arraynum, const bool bussed, const int msb,
const int lsb) {
const int bits = ((msb > lsb) ? (msb - lsb) : (lsb - msb)) + 1;
const std::string hierarchicalName = m_prefixStack.back().first + name;
if (!Super::declCode(code, hierarchicalName, bits)) return;
const size_t block_size = 1024; const size_t block_size = 1024;
if (m_activityArena.empty() if (m_activityArena.empty()
|| m_activityArena.back().size() + bits > m_activityArena.back().capacity()) { || m_activityArena.back().size() + bits > m_activityArena.back().capacity()) {
@ -328,56 +336,70 @@ void VerilatedSaif::declare(const uint32_t code, const char* name, const char* w
const size_t bitsIdx = m_activityArena.back().size(); const size_t bitsIdx = m_activityArena.back().size();
m_activityArena.back().resize(m_activityArena.back().size() + bits); m_activityArena.back().resize(m_activityArena.back().size() + bits);
std::string finalName = lastWord(hierarchicalName);
if (array) { if (array) {
finalName += '['; variableName += '[';
finalName += std::to_string(arraynum); variableName += std::to_string(arraynum);
finalName += ']'; variableName += ']';
} }
assert(m_currentScope >= 0); m_scopeToActivities[absoluteScopePath].emplace_back(code, variableName);
m_scopes.at(m_currentScope).addActivityVar(code, std::move(finalName)); m_activity.emplace(code, VerilatedSaifActivityVar{
static_cast<uint32_t>(bits), m_activityArena.back().data() + bitsIdx});
}
m_activity.emplace(code, VerilatedSaifActivityVar{static_cast<uint32_t>(bits), void VerilatedSaif::declare(const uint32_t code, uint32_t fidx, const char* name, const char* wirep,
m_activityArena.back().data() + bitsIdx}); const bool array, const int arraynum, const bool bussed, const int msb,
const int lsb) {
VerilatedSaifActivityAccumulator& accumulator = m_activityAccumulators.at(fidx);
const int bits = ((msb > lsb) ? (msb - lsb) : (lsb - msb)) + 1;
const std::string hierarchicalName = m_prefixStack.back().first + name;
if (!Super::declCode(code, hierarchicalName, bits)) return;
std::string variableName = lastWord(hierarchicalName);
m_scopes.at(m_currentScope).addActivityVar(code, variableName);
accumulator.declare(code, m_scopes.at(m_currentScope).path(), std::move(variableName), bits, array, arraynum);
} }
void VerilatedSaif::declEvent(const uint32_t code, const uint32_t fidx, const char* name, void VerilatedSaif::declEvent(const uint32_t code, const uint32_t fidx, const char* name,
const int dtypenum, const VerilatedTraceSigDirection, const int dtypenum, const VerilatedTraceSigDirection,
const VerilatedTraceSigKind, const VerilatedTraceSigType, const VerilatedTraceSigKind, const VerilatedTraceSigType,
const bool array, const int arraynum) { const bool array, const int arraynum) {
declare(code, name, "event", array, arraynum, false, 0, 0); declare(code, fidx, name, "event", array, arraynum, false, 0, 0);
} }
void VerilatedSaif::declBit(const uint32_t code, const uint32_t fidx, const char* name, void VerilatedSaif::declBit(const uint32_t code, const uint32_t fidx, const char* name,
const int dtypenum, const VerilatedTraceSigDirection, const int dtypenum, const VerilatedTraceSigDirection,
const VerilatedTraceSigKind, const VerilatedTraceSigType, const VerilatedTraceSigKind, const VerilatedTraceSigType,
const bool array, const int arraynum) { const bool array, const int arraynum) {
declare(code, name, "wire", array, arraynum, false, 0, 0); declare(code, fidx, name, "wire", array, arraynum, false, 0, 0);
} }
void VerilatedSaif::declBus(const uint32_t code, const uint32_t fidx, const char* name, void VerilatedSaif::declBus(const uint32_t code, const uint32_t fidx, const char* name,
const int dtypenum, const VerilatedTraceSigDirection, const int dtypenum, const VerilatedTraceSigDirection,
const VerilatedTraceSigKind, const VerilatedTraceSigType, const VerilatedTraceSigKind, const VerilatedTraceSigType,
const bool array, const int arraynum, const int msb, const int lsb) { const bool array, const int arraynum, const int msb, const int lsb) {
declare(code, name, "wire", array, arraynum, true, msb, lsb); declare(code, fidx, name, "wire", array, arraynum, true, msb, lsb);
} }
void VerilatedSaif::declQuad(const uint32_t code, const uint32_t fidx, const char* name, void VerilatedSaif::declQuad(const uint32_t code, const uint32_t fidx, const char* name,
const int dtypenum, const VerilatedTraceSigDirection, const int dtypenum, const VerilatedTraceSigDirection,
const VerilatedTraceSigKind, const VerilatedTraceSigType, const VerilatedTraceSigKind, const VerilatedTraceSigType,
const bool array, const int arraynum, const int msb, const int lsb) { const bool array, const int arraynum, const int msb, const int lsb) {
declare(code, name, "wire", array, arraynum, true, msb, lsb); declare(code, fidx, name, "wire", array, arraynum, true, msb, lsb);
} }
void VerilatedSaif::declArray(const uint32_t code, const uint32_t fidx, const char* name, void VerilatedSaif::declArray(const uint32_t code, const uint32_t fidx, const char* name,
const int dtypenum, const VerilatedTraceSigDirection, const int dtypenum, const VerilatedTraceSigDirection,
const VerilatedTraceSigKind, const VerilatedTraceSigType, const VerilatedTraceSigKind, const VerilatedTraceSigType,
const bool array, const int arraynum, const int msb, const int lsb) { const bool array, const int arraynum, const int msb, const int lsb) {
declare(code, name, "wire", array, arraynum, true, msb, lsb); declare(code, fidx, name, "wire", array, arraynum, true, msb, lsb);
} }
void VerilatedSaif::declDouble(const uint32_t code, const uint32_t fidx, const char* name, void VerilatedSaif::declDouble(const uint32_t code, const uint32_t fidx, const char* name,
const int dtypenum, const VerilatedTraceSigDirection, const int dtypenum, const VerilatedTraceSigDirection,
const VerilatedTraceSigKind, const VerilatedTraceSigType, const VerilatedTraceSigKind, const VerilatedTraceSigType,
const bool array, const int arraynum) { const bool array, const int arraynum) {
declare(code, name, "real", array, arraynum, false, 63, 0); declare(code, fidx, name, "real", array, arraynum, false, 63, 0);
} }
//============================================================================= //=============================================================================
@ -404,43 +426,43 @@ void VerilatedSaifBuffer::emitEvent(const uint32_t code) {
VL_ATTR_ALWINLINE VL_ATTR_ALWINLINE
void VerilatedSaifBuffer::emitBit(const uint32_t code, const CData newval) { void VerilatedSaifBuffer::emitBit(const uint32_t code, const CData newval) {
assert(m_owner.m_activity.count(code) && "Activity must be declared earlier"); assert(m_owner.m_activityAccumulators.at(m_fidx).m_activity.count(code) && "Activity must be declared earlier");
VerilatedSaifActivityVar& activity = m_owner.m_activity.at(code); VerilatedSaifActivityVar& activity = m_owner.m_activityAccumulators.at(m_fidx).m_activity.at(code);
activity.emitBit(m_owner.currentTime(), newval); activity.emitBit(m_owner.currentTime(), newval);
} }
VL_ATTR_ALWINLINE VL_ATTR_ALWINLINE
void VerilatedSaifBuffer::emitCData(const uint32_t code, const CData newval, const int bits) { void VerilatedSaifBuffer::emitCData(const uint32_t code, const CData newval, const int bits) {
assert(m_owner.m_activity.count(code) && "Activity must be declared earlier"); assert(m_owner.m_activityAccumulators.at(m_fidx).m_activity.count(code) && "Activity must be declared earlier");
VerilatedSaifActivityVar& activity = m_owner.m_activity.at(code); VerilatedSaifActivityVar& activity = m_owner.m_activityAccumulators.at(m_fidx).m_activity.at(code);
activity.emitData<CData>(m_owner.currentTime(), newval, bits); activity.emitData<CData>(m_owner.currentTime(), newval, bits);
} }
VL_ATTR_ALWINLINE VL_ATTR_ALWINLINE
void VerilatedSaifBuffer::emitSData(const uint32_t code, const SData newval, const int bits) { void VerilatedSaifBuffer::emitSData(const uint32_t code, const SData newval, const int bits) {
assert(m_owner.m_activity.count(code) && "Activity must be declared earlier"); assert(m_owner.m_activityAccumulators.at(m_fidx).m_activity.count(code) && "Activity must be declared earlier");
VerilatedSaifActivityVar& activity = m_owner.m_activity.at(code); VerilatedSaifActivityVar& activity = m_owner.m_activityAccumulators.at(m_fidx).m_activity.at(code);
activity.emitData<SData>(m_owner.currentTime(), newval, bits); activity.emitData<SData>(m_owner.currentTime(), newval, bits);
} }
VL_ATTR_ALWINLINE VL_ATTR_ALWINLINE
void VerilatedSaifBuffer::emitIData(const uint32_t code, const IData newval, const int bits) { void VerilatedSaifBuffer::emitIData(const uint32_t code, const IData newval, const int bits) {
assert(m_owner.m_activity.count(code) && "Activity must be declared earlier"); assert(m_owner.m_activityAccumulators.at(m_fidx).m_activity.count(code) && "Activity must be declared earlier");
VerilatedSaifActivityVar& activity = m_owner.m_activity.at(code); VerilatedSaifActivityVar& activity = m_owner.m_activityAccumulators.at(m_fidx).m_activity.at(code);
activity.emitData<IData>(m_owner.currentTime(), newval, bits); activity.emitData<IData>(m_owner.currentTime(), newval, bits);
} }
VL_ATTR_ALWINLINE VL_ATTR_ALWINLINE
void VerilatedSaifBuffer::emitQData(const uint32_t code, const QData newval, const int bits) { void VerilatedSaifBuffer::emitQData(const uint32_t code, const QData newval, const int bits) {
assert(m_owner.m_activity.count(code) && "Activity must be declared earlier"); assert(m_owner.m_activityAccumulators.at(m_fidx).m_activity.count(code) && "Activity must be declared earlier");
VerilatedSaifActivityVar& activity = m_owner.m_activity.at(code); VerilatedSaifActivityVar& activity = m_owner.m_activityAccumulators.at(m_fidx).m_activity.at(code);
activity.emitData<QData>(m_owner.currentTime(), newval, bits); activity.emitData<QData>(m_owner.currentTime(), newval, bits);
} }
VL_ATTR_ALWINLINE VL_ATTR_ALWINLINE
void VerilatedSaifBuffer::emitWData(const uint32_t code, const WData* newvalp, const int bits) { void VerilatedSaifBuffer::emitWData(const uint32_t code, const WData* newvalp, const int bits) {
assert(m_owner.m_activity.count(code) && "Activity must be declared earlier"); assert(m_owner.m_activityAccumulators.at(m_fidx).m_activity.count(code) && "Activity must be declared earlier");
VerilatedSaifActivityVar& activity = m_owner.m_activity.at(code); VerilatedSaifActivityVar& activity = m_owner.m_activityAccumulators.at(m_fidx).m_activity.at(code);
activity.emitWData(m_owner.currentTime(), newvalp, bits); activity.emitWData(m_owner.currentTime(), newvalp, bits);
} }

View File

@ -106,16 +106,22 @@ private:
class VerilatedSaifActivityScope final { class VerilatedSaifActivityScope final {
// MEMBERS // MEMBERS
std::string m_scopeName{}; // name of the activity scope // absolute path to the scope
std::vector<int32_t> m_childScopesIndices{}; // array indices of child scopes std::string m_scopePath{};
std::vector<std::pair<uint32_t, std::string>> // name of the activity scope
m_childActivities{}; // children signals codes mapped to their names in the current scope std::string m_scopeName{};
int32_t m_parentScopeIndex{-1}; // array index of parent scope // array indices of child scopes
std::vector<int32_t> m_childScopesIndices{};
// children signals codes mapped to their names in the current scope
std::vector<std::pair<uint32_t, std::string>> m_childActivities{};
// array index of parent scope
int32_t m_parentScopeIndex{-1};
public: public:
// CONSTRUCTORS // CONSTRUCTORS
VerilatedSaifActivityScope(std::string name, int32_t parentScopeIndex = -1) VerilatedSaifActivityScope(std::string scopePath, std::string name, int32_t parentScopeIndex = -1)
: m_scopeName{std::move(name)} : m_scopePath{std::move(scopePath)}
, m_scopeName{std::move(name)}
, m_parentScopeIndex{parentScopeIndex} {} , m_parentScopeIndex{parentScopeIndex} {}
VerilatedSaifActivityScope(VerilatedSaifActivityScope&&) = default; VerilatedSaifActivityScope(VerilatedSaifActivityScope&&) = default;
@ -131,6 +137,7 @@ public:
VL_ATTR_ALWINLINE bool hasParent() const { return m_parentScopeIndex >= 0; } VL_ATTR_ALWINLINE bool hasParent() const { return m_parentScopeIndex >= 0; }
// ACCESSORS // ACCESSORS
VL_ATTR_ALWINLINE const std::string& path() const { return m_scopePath; }
VL_ATTR_ALWINLINE const std::string& name() const { return m_scopeName; } VL_ATTR_ALWINLINE const std::string& name() const { return m_scopeName; }
VL_ATTR_ALWINLINE const std::vector<int32_t>& childScopesIndices() const { VL_ATTR_ALWINLINE const std::vector<int32_t>& childScopesIndices() const {
return m_childScopesIndices; return m_childScopesIndices;
@ -146,6 +153,33 @@ private:
VL_UNCOPYABLE(VerilatedSaifActivityScope); VL_UNCOPYABLE(VerilatedSaifActivityScope);
}; };
class VerilatedSaifActivityAccumulator {
// Give access to the private activities
friend class VerilatedSaifBuffer;
friend class VerilatedSaif;
// MEMBERS
// map of scopes paths to codes of activities inside
std::unordered_map<std::string, std::vector<std::pair<uint32_t, std::string>>> m_scopeToActivities;
// map of variables codes mapped to their activity objects
std::unordered_map<uint32_t, VerilatedSaifActivityVar> m_activity;
// memory pool for signals bits objects
std::vector<std::vector<VerilatedSaifActivityBit>> m_activityArena;
public:
// METHODS
void declare(uint32_t code, const std::string& absoluteScopePath, std::string variableName, int bits, bool array, int arraynum);
// CONSTRUCTORS
VerilatedSaifActivityAccumulator() = default;
VerilatedSaifActivityAccumulator(VerilatedSaifActivityAccumulator&&) = default;
VerilatedSaifActivityAccumulator& operator=(VerilatedSaifActivityAccumulator&&) = default;
private:
VL_UNCOPYABLE(VerilatedSaifActivityAccumulator);
};
//============================================================================= //=============================================================================
// VerilatedSaif // VerilatedSaif
// Base class to create a Verilator SAIF dump // Base class to create a Verilator SAIF dump
@ -167,14 +201,14 @@ private:
int m_indent = 0; // indentation size in spaces int m_indent = 0; // indentation size in spaces
int32_t m_currentScope{-1}; // currently active scope // currently active scope
std::vector<VerilatedSaifActivityScope> m_scopes{}; // array of declared scopes int32_t m_currentScope{-1};
std::vector<int32_t> m_topScopes{}; // array of top scopes // array of declared scopes
std::vector<VerilatedSaifActivityScope> m_scopes{};
std::unordered_map<uint32_t, VerilatedSaifActivityVar> // array of top scopes
m_activity; // map of variables codes mapped to their activity objects std::vector<int32_t> m_topScopes{};
std::vector<std::vector<VerilatedSaifActivityBit>> // activity accumulators used to store variables statistics over simulation time
m_activityArena; // memory pool for signals bits objects std::vector<VerilatedSaifActivityAccumulator> m_activityAccumulators{};
uint64_t m_time{0}; // total time of the currently traced simulation uint64_t m_time{0}; // total time of the currently traced simulation
@ -191,9 +225,10 @@ private:
void openInstanceScope(const std::string& instanceName); void openInstanceScope(const std::string& instanceName);
void closeInstanceScope(); void closeInstanceScope();
void printScopeActivities(const VerilatedSaifActivityScope& scope); void printScopeActivities(const VerilatedSaifActivityScope& scope);
bool printScopeActivitiesFromAccumulatorIfPresent(const std::string& absoluteScopePath, VerilatedSaifActivityAccumulator& accumulator, bool anyNetWritten);
void openNetScope(); void openNetScope();
void closeNetScope(); void closeNetScope();
bool printActivityStats(uint32_t activityCode, const char* activityName, bool anyNetValid); bool printActivityStats(VerilatedSaifActivityVar& activity, const char* activityName, bool anyNetWritten);
void incrementIndent(); void incrementIndent();
void decrementIndent(); void decrementIndent();
@ -204,7 +239,7 @@ private:
void clearCurrentlyCollectedData(); void clearCurrentlyCollectedData();
void declare(uint32_t code, const char* name, const char* wirep, bool array, int arraynum, void declare(uint32_t code, uint32_t fidx, const char* name, const char* wirep, bool array, int arraynum,
bool bussed, int msb, int lsb); bool bussed, int msb, int lsb);
// CONSTRUCTORS // CONSTRUCTORS
@ -236,11 +271,6 @@ public:
explicit VerilatedSaif(void* filep = nullptr); explicit VerilatedSaif(void* filep = nullptr);
~VerilatedSaif(); ~VerilatedSaif();
// ACCESSORS
// Set size in bytes after which new file should be created.
void rolloverSize(uint64_t size) VL_MT_SAFE { /* noop */
}
// METHODS - All must be thread safe // METHODS - All must be thread safe
// Open the file; call isOpen() to see if errors // Open the file; call isOpen() to see if errors
void open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex); void open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex);
@ -304,10 +334,13 @@ class VerilatedSaifBuffer VL_NOT_FINAL {
friend VerilatedSaif::OffloadBuffer; friend VerilatedSaif::OffloadBuffer;
VerilatedSaif& m_owner; // Trace file owning this buffer. Required by subclasses. VerilatedSaif& m_owner; // Trace file owning this buffer. Required by subclasses.
uint32_t m_fidx; // Index of target activity accumulator
// CONSTRUCTOR // CONSTRUCTOR
explicit VerilatedSaifBuffer(VerilatedSaif& owner) explicit VerilatedSaifBuffer(VerilatedSaif& owner)
: m_owner{owner} {} : m_owner{owner}, m_fidx{0} {}
explicit VerilatedSaifBuffer(VerilatedSaif& owner, uint32_t fidx)
: m_owner{owner}, m_fidx{fidx} {}
virtual ~VerilatedSaifBuffer() = default; virtual ~VerilatedSaifBuffer() = default;
//========================================================================= //=========================================================================
@ -351,8 +384,7 @@ public:
/// just as if this object was deleted and reconstructed. /// just as if this object was deleted and reconstructed.
virtual void open(const char* filename) VL_MT_SAFE { m_sptrace.open(filename); } virtual void open(const char* filename) VL_MT_SAFE { m_sptrace.open(filename); }
void rolloverSize(size_t size) VL_MT_SAFE { /* noop */ void rolloverSize(size_t size) VL_MT_SAFE {/* noop */}
}
/// Close dump /// Close dump
void close() VL_MT_SAFE { void close() VL_MT_SAFE {