diff --git a/src/V3EmitCBase.cpp b/src/V3EmitCBase.cpp index 3c7ebc3d4..424fa82bd 100644 --- a/src/V3EmitCBase.cpp +++ b/src/V3EmitCBase.cpp @@ -67,6 +67,7 @@ AstCFile* EmitCBaseVisitorConst::createCFile(const string& filename, bool slow, AstCFile* const cfilep = new AstCFile{v3Global.rootp()->fileline(), filename}; cfilep->slow(slow); cfilep->source(source); + if (source) V3Stats::addStatSum(V3Stats::STAT_CPP_FILES, 1); return cfilep; } diff --git a/src/V3File.h b/src/V3File.h index 9d1066a82..2106f908e 100644 --- a/src/V3File.h +++ b/src/V3File.h @@ -21,6 +21,7 @@ #include "verilatedos.h" #include "V3Error.h" +#include "V3Stats.h" #include #include @@ -207,6 +208,7 @@ class V3OutFile VL_NOT_FINAL : public V3OutFormatter { // MEMBERS FILE* m_fp = nullptr; std::size_t m_usedBytes = 0; // Number of bytes stored in m_bufferp + std::size_t m_writtenBytes = 0; // Number of bytes written to output std::unique_ptr> m_bufferp; // Write buffer public: @@ -215,16 +217,23 @@ public: V3OutFile& operator=(const V3OutFile&) = delete; V3OutFile(V3OutFile&&) = delete; V3OutFile& operator=(V3OutFile&&) = delete; - ~V3OutFile() override; + void putsForceIncs(); + void statRecordWritten() { + writeBlock(); + V3Stats::addStatSum(V3Stats::STAT_CPP_CHARS, m_writtenBytes); + } + private: void writeBlock() { - if (VL_LIKELY(m_usedBytes > 0)) fwrite(m_bufferp->data(), m_usedBytes, 1, m_fp); - m_usedBytes = 0; + if (VL_LIKELY(m_usedBytes > 0)) { + fwrite(m_bufferp->data(), m_usedBytes, 1, m_fp); + m_writtenBytes += m_usedBytes; + m_usedBytes = 0; + } } - // CALLBACKS void putcOutput(char chr) override { m_bufferp->at(m_usedBytes++) = chr; @@ -257,7 +266,7 @@ public: : V3OutFile{filename, lang} { resetPrivate(); } - ~V3OutCFile() override = default; + ~V3OutCFile() override { statRecordWritten(); } virtual void putsHeader() { puts("// Verilated -*- C++ -*-\n"); } virtual void putsIntTopInclude() { putsForceIncs(); } virtual void putsGuard(); diff --git a/src/V3Stats.cpp b/src/V3Stats.cpp index 0312c6458..0212d2816 100644 --- a/src/V3Stats.cpp +++ b/src/V3Stats.cpp @@ -23,6 +23,11 @@ VL_DEFINE_DEBUG_FUNCTIONS; +//###################################################################### +// Statics + +V3Mutex V3Stats::s_mutex; + //###################################################################### // Stats class functions @@ -165,6 +170,11 @@ public: //###################################################################### // Top Stats class +void V3Stats::addStatSum(const string& name, double count) VL_MT_SAFE_EXCLUDES(s_mutex) { + V3LockGuard lock{s_mutex}; + addStat(V3Statistic{"*", name, count, 0, true}); +} + void V3Stats::statsStageAll(AstNetlist* nodep, const std::string& stage, bool fastOnly) { StatsVisitor{nodep, stage, fastOnly}; } diff --git a/src/V3Stats.h b/src/V3Stats.h index 7c3a8ea1c..33f100723 100644 --- a/src/V3Stats.h +++ b/src/V3Stats.h @@ -103,8 +103,12 @@ public: //============================================================================ class V3Stats final { + static V3Mutex s_mutex; // Protects accesses + public: // Symbolic names for some statistics that are later read by summaryReport() + static constexpr const char* STAT_CPP_CHARS = "Output, C++ bytes written"; + static constexpr const char* STAT_CPP_FILES = "Output, C++ files written"; static constexpr const char* STAT_MODEL_SIZE = "Size prediction, Model total (bytes)"; static constexpr const char* STAT_SOURCE_CHARS = "Input, Verilog bytes read"; static constexpr const char* STAT_SOURCE_MODULES = "Input, Verilog modules read"; @@ -117,9 +121,8 @@ public: static void addStat(const string& name, double value, unsigned precision = 0) { addStat(V3Statistic{"*", name, value, precision}); } - static void addStatSum(const string& name, double count) { - addStat(V3Statistic{"*", name, count, 0, true}); - } + // Add summary statistic - Threadsafe _unlike most other functions here_ + static void addStatSum(const string& name, double count) VL_MT_SAFE_EXCLUDES(s_mutex); static void addStatPerf(const string& name, double value) { addStat(V3Statistic{"*", name, value, 6, true, true}); }