Use parser thread in StlPlayer.

This commit is contained in:
Lukas Steiner
2020-09-25 11:34:32 +02:00
parent 6042e05ba2
commit 34175aebc3

View File

@@ -41,6 +41,9 @@
#define STLPLAYER_H
#include <sstream>
#include <vector>
#include <array>
#include <thread>
#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<LineContent>::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<relative>::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<LineContent> lineContents;
static constexpr unsigned lineBufferSize = 10000;
std::vector<LineContent> *currentBuffer;
std::vector<LineContent> *parseBuffer;
std::array<std::vector<LineContent>, 2> lineContents;
std::vector<LineContent>::const_iterator lineIterator;
std::thread parserThread;
std::string time;
std::string command;
std::string address;