Use parser thread in StlPlayer.
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user