From 2499c71d1256ee74fd25d3716fc6fb9f3d3f529f Mon Sep 17 00:00:00 2001 From: Mateusz Gancarz Date: Wed, 5 Mar 2025 08:46:08 +0100 Subject: [PATCH] [#74021] simplify file IO logic --- include/verilated_saif_c.cpp | 67 +++++------------------------------- include/verilated_saif_c.h | 44 ++++------------------- 2 files changed, 15 insertions(+), 96 deletions(-) diff --git a/include/verilated_saif_c.cpp b/include/verilated_saif_c.cpp index 94499b815..1f98a7d5b 100644 --- a/include/verilated_saif_c.cpp +++ b/include/verilated_saif_c.cpp @@ -89,50 +89,26 @@ VerilatedSaifActivityBit& VerilatedSaifActivityVar::bit(const std::size_t index) return m_bits[index]; } -//============================================================================= -//============================================================================= -//============================================================================= -// VerilatedSaifFile - -bool VerilatedSaifFile::open(const std::string& name) VL_MT_UNSAFE { - m_fd = ::open(name.c_str(), - O_CREAT | O_WRONLY | O_TRUNC | O_LARGEFILE | O_NONBLOCK | O_CLOEXEC, 0666); - return m_fd >= 0; -} - -void VerilatedSaifFile::close() VL_MT_UNSAFE { ::close(m_fd); } - -ssize_t VerilatedSaifFile::write(const char* bufp, ssize_t len) VL_MT_UNSAFE { - return ::write(m_fd, bufp, len); -} - //============================================================================= //============================================================================= //============================================================================= // Opening/Closing -VerilatedSaif::VerilatedSaif(VerilatedSaifFile* filep) { - // Not in header to avoid link issue if header is included without this .cpp file - m_fileNewed = (filep == nullptr); - m_filep = m_fileNewed ? new VerilatedSaifFile : filep; -} +VerilatedSaif::VerilatedSaif(void* filep) {} void VerilatedSaif::open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) { const VerilatedLockGuard lock{m_mutex}; if (isOpen()) return; - // Set member variables m_filename = filename; // "" is ok, as someone may overload open + m_filep = ::open(m_filename.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_LARGEFILE | O_NONBLOCK | O_CLOEXEC, 0666); + m_isOpen = true; initializeSaifFileContents(); Super::traceInit(); } -void VerilatedSaif::openNext(bool incFilename) VL_MT_SAFE_EXCLUDES(m_mutex) { - // noop, SAIF only needs one file per trace -} - void VerilatedSaif::initializeSaifFileContents() { printStr("// Generated by verilated_saif\n"); printStr("(SAIFILE\n"); @@ -145,34 +121,9 @@ void VerilatedSaif::initializeSaifFileContents() { printStr(")\n"); } -bool VerilatedSaif::preChangeDump() { return isOpen(); } - void VerilatedSaif::emitTimeChange(uint64_t timeui) { m_time = timeui; } -VerilatedSaif::~VerilatedSaif() { - close(); - if (m_filep && m_fileNewed) VL_DO_CLEAR(delete m_filep, m_filep = nullptr); -} - -void VerilatedSaif::closePrev() { - // This function is on the flush() call path - if (!isOpen()) return; - - Super::flushBase(); - m_isOpen = false; - m_filep->close(); -} - -void VerilatedSaif::closeErr() { - // This function is on the flush() call path - // Close due to an error. We might abort before even getting here, - // depending on the definition of vl_fatal. - if (!isOpen()) return; - - // No buffer flush, just fclose - m_isOpen = false; - m_filep->close(); // May get error, just ignore it -} +VerilatedSaif::~VerilatedSaif() { close(); } void VerilatedSaif::close() VL_MT_SAFE_EXCLUDES(m_mutex) { // This function is on the flush() call path @@ -182,9 +133,9 @@ void VerilatedSaif::close() VL_MT_SAFE_EXCLUDES(m_mutex) { finalizeSaifFileContents(); clearCurrentlyCollectedData(); - closePrev(); - // closePrev() called Super::flush(), so we just - // need to shut down the tracing thread here. + ::close(m_filep); + m_isOpen = false; + Super::closeBase(); } @@ -298,9 +249,9 @@ void VerilatedSaif::clearCurrentlyCollectedData() { m_activityArena.clear(); } -void VerilatedSaif::printStr(const char* str) { m_filep->write(str, strlen(str)); } +void VerilatedSaif::printStr(const char* str) { ::write(m_filep, str, strlen(str)); } -void VerilatedSaif::printStr(const std::string& str) { m_filep->write(str.c_str(), str.size()); } +void VerilatedSaif::printStr(const std::string& str) { ::write(m_filep, str.c_str(), str.size()); } //============================================================================= // Definitions diff --git a/include/verilated_saif_c.h b/include/verilated_saif_c.h index a6c32a4bc..b16fc262e 100644 --- a/include/verilated_saif_c.h +++ b/include/verilated_saif_c.h @@ -161,8 +161,7 @@ private: //========================================================================= // SAIF-specific internals - VerilatedSaifFile* m_filep; // File we're writing to - bool m_fileNewed; // m_filep needs destruction + int m_filep = 0; // File we're writing to bool m_isOpen = false; // True indicates open file std::string m_filename; // Filename we're writing to (if open) @@ -205,8 +204,6 @@ private: void clearCurrentlyCollectedData(); - void closePrev(); - void closeErr(); void declare(uint32_t code, const char* name, const char* wirep, bool array, int arraynum, bool bussed, int msb, int lsb); @@ -222,7 +219,7 @@ protected: // Hooks called from VerilatedTrace bool preFullDump() override { return isOpen(); } - bool preChangeDump() override; + bool preChangeDump() override { return isOpen(); } // Trace buffer management Buffer* getTraceBuffer(uint32_t fidx) override; @@ -236,7 +233,7 @@ public: // External interface to client code // CONSTRUCTOR - explicit VerilatedSaif(VerilatedSaifFile* filep = nullptr); + explicit VerilatedSaif(void* filep = nullptr); ~VerilatedSaif(); // ACCESSORS @@ -247,8 +244,6 @@ public: // METHODS - All must be thread safe // Open the file; call isOpen() to see if errors void open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex); - // Open next data-only file - void openNext(bool incFilename) VL_MT_SAFE_EXCLUDES(m_mutex); // Close the file void close() VL_MT_SAFE_EXCLUDES(m_mutex); // Flush any remaining data to this file @@ -329,28 +324,6 @@ class VerilatedSaifBuffer VL_NOT_FINAL { VL_ATTR_ALWINLINE void emitDouble(uint32_t code, double newval); }; -//============================================================================= -// VerilatedFile -/// Class representing a file to write to. These virtual methods can be -/// overrode for e.g. socket I/O. - -class VerilatedSaifFile VL_NOT_FINAL { -private: - int m_fd = 0; // File descriptor we're writing to -public: - // METHODS - /// Construct a (as yet) closed file - VerilatedSaifFile() = default; - /// Close and destruct - virtual ~VerilatedSaifFile() = default; - /// Open a file with given filename - virtual bool open(const std::string& name) VL_MT_UNSAFE; - /// Close object's file - virtual void close() VL_MT_UNSAFE; - /// Write data to file (if it is open) - virtual ssize_t write(const char* bufp, ssize_t len) VL_MT_UNSAFE; -}; - //============================================================================= // VerilatedSaifC /// Class representing a SAIF dump file in C standalone (no SystemC) @@ -363,8 +336,8 @@ class VerilatedSaifC VL_NOT_FINAL : public VerilatedTraceBaseC { VL_UNCOPYABLE(VerilatedSaifC); public: - /// Construct the dump. Optional argument is a preconstructed file. - explicit VerilatedSaifC(VerilatedSaifFile* filep = nullptr) + /// Construct the dump. Optional argument is ignored + explicit VerilatedSaifC(void* filep = nullptr) : m_sptrace{filep} {} /// Destruct, flush, and close the dump virtual ~VerilatedSaifC() { close(); } @@ -377,13 +350,8 @@ public: /// This includes a complete header dump each time it is called, /// just as if this object was deleted and reconstructed. virtual void open(const char* filename) VL_MT_SAFE { m_sptrace.open(filename); } - /// Continue a SAIF dump by rotating to a new file name - /// The header is only in the first file created, this allows - /// "cat" to be used to combine the header plus any number of data files. - void openNext(bool incFilename = true) VL_MT_SAFE { m_sptrace.openNext(incFilename); } - void rolloverSize(size_t size) VL_MT_SAFE { /* noop */ - } + void rolloverSize(size_t size) VL_MT_SAFE { /* noop */ } /// Close dump void close() VL_MT_SAFE {