diff --git a/DRAMSys/simulator/StlPlayer.h b/DRAMSys/simulator/StlPlayer.h index 4eb89af1..787f00d5 100644 --- a/DRAMSys/simulator/StlPlayer.h +++ b/DRAMSys/simulator/StlPlayer.h @@ -41,6 +41,9 @@ #define STLPLAYER_H #include +#include +#include +#include #include "TracePlayer.h" struct LineContent @@ -60,7 +63,9 @@ public: sc_time playerClk, TracePlayerListener *listener) : TracePlayer(name, listener), - file(pathToTrace) + file(pathToTrace), + currentBuffer(&lineContents[0]), + parseBuffer(&lineContents[1]) { if (!file.is_open()) SC_REPORT_FATAL(0, (std::string("Could not open trace ") + pathToTrace).c_str()); @@ -70,14 +75,25 @@ public: dataLength = Configuration::getInstance().getBytesPerBurst(); lineCnt = 0; + currentBuffer->reserve(lineBufferSize); + parseBuffer->reserve(lineBufferSize); + parseTraceFile(); + lineIterator = currentBuffer->cend(); } + ~StlPlayer() + { + if (parserThread.joinable()) + parserThread.join(); + } + +private: void parseTraceFile() { unsigned parsedLines = 0; - lineContents.clear(); - while (file && !file.eof() && parsedLines < 10000) + parseBuffer->clear(); + while (file && !file.eof() && parsedLines < lineBufferSize) { // Get a new line from the input file. std::getline(file, line); @@ -87,8 +103,8 @@ public: continue; parsedLines++; - lineContents.emplace_back(); - LineContent &content = lineContents.back(); + parseBuffer->emplace_back(); + LineContent &content = parseBuffer->back(); // Trace files MUST provide timestamp, command and address for every // transaction. The data information depends on the storage mode @@ -155,16 +171,30 @@ public: content.data.emplace_back((unsigned char)std::stoi(dataStr.substr(i * 2 + 2, 2).c_str(), nullptr, 16)); } } - lineIterator = lineContents.cbegin(); } + std::vector::const_iterator swapBuffers() + { + // Wait for parser to finish + if (parserThread.joinable()) + parserThread.join(); + + // Swap buffers + std::swap(currentBuffer, parseBuffer); + + // Start new parser thread + parserThread = std::thread(&StlPlayer::parseTraceFile, this); + + return currentBuffer->cbegin(); + } + +public: void nextPayload() { - if (lineIterator == lineContents.cend()) + if (lineIterator == currentBuffer->cend()) { - // Read new lines of file. - parseTraceFile(); - if (lineIterator == lineContents.cend()) + lineIterator = swapBuffers(); + if (lineIterator == currentBuffer->cend()) { // The file is empty. Nothing more to do. this->finish(); @@ -211,9 +241,15 @@ private: unsigned int dataLength; sc_time playerClk; // May be different from the memory clock! - std::vector lineContents; + static constexpr unsigned lineBufferSize = 10000; + + std::vector *currentBuffer; + std::vector *parseBuffer; + std::array, 2> lineContents; std::vector::const_iterator lineIterator; + std::thread parserThread; + std::string time; std::string command; std::string address;