From f146a7f7f17ad34fccd8a99bf73dbb10cd3afa01 Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Sun, 25 Apr 2021 22:07:59 -0400 Subject: [PATCH] Added a separate thread to Qt trace logger whose job is to just write the logged instructions to disk (when disk logging is enabled only). This allows for bottle necks with disk I/O to not slow down the emulation. Also, buffer 4k blocks before writing to disk to make more efficient. --- src/drivers/Qt/ConsoleWindow.cpp | 5 +- src/drivers/Qt/ConsoleWindow.h | 2 +- src/drivers/Qt/TraceLogger.cpp | 136 ++++++++++++++++++++++++++----- src/drivers/Qt/TraceLogger.h | 19 +++++ 4 files changed, 138 insertions(+), 24 deletions(-) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index f5b22daf..3f79ba76 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -139,7 +139,7 @@ consoleWin_t::consoleWin_t(QWidget *parent) #else mutex = new QMutex( QMutex::Recursive ); #endif - emulatorThread = new emulatorThread_t(); + emulatorThread = new emulatorThread_t(this); connect(emulatorThread, &QThread::finished, emulatorThread, &QObject::deleteLater); @@ -3370,7 +3370,8 @@ void consoleWin_t::updatePeriodic(void) return; } -emulatorThread_t::emulatorThread_t(void) +emulatorThread_t::emulatorThread_t( QObject *parent ) + : QThread(parent) { #if defined(__linux__) || defined(__APPLE__) || defined(__unix__) pself = 0; diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index df17c914..fcb78acc 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -36,7 +36,7 @@ class emulatorThread_t : public QThread void run( void ) override; public: - emulatorThread_t(void); + emulatorThread_t( QObject *parent = 0 ); void setPriority( QThread::Priority priority ); diff --git a/src/drivers/Qt/TraceLogger.cpp b/src/drivers/Qt/TraceLogger.cpp index f75fde29..cb3202e6 100644 --- a/src/drivers/Qt/TraceLogger.cpp +++ b/src/drivers/Qt/TraceLogger.cpp @@ -99,6 +99,10 @@ static traceRecord_t *recBuf = NULL; static int recBufMax = 0; static int recBufHead = 0; static int recBufTail = 0; +static traceRecord_t *logBuf = NULL; +static int logBufMax = 1000000; +static int logBufHead = 0; +static int logBufTail = 0; static FILE *logFile = NULL; static bool overrunWarningArmed = true; static TraceLoggerDialog_t *traceLogWindow = NULL; @@ -311,21 +315,23 @@ TraceLoggerDialog_t::TraceLoggerDialog_t(QWidget *parent) connect(updateTimer, &QTimer::timeout, this, &TraceLoggerDialog_t::updatePeriodic); - updateTimer->start(10); // 100hz + updateTimer->start(50); // 20hz + + diskThread = new TraceLogDiskThread_t(this); } //---------------------------------------------------- TraceLoggerDialog_t::~TraceLoggerDialog_t(void) { updateTimer->stop(); - traceLogWindow = NULL; logging = 0; + msleep(1); + diskThread->requestInterruption(); + diskThread->quit(); + diskThread->wait( 1000 ); + + traceLogWindow = NULL; - if (logFile) - { - fclose(logFile); - logFile = NULL; - } printf("Trace Logger Window Deleted\n"); } //---------------------------------------------------- @@ -366,16 +372,16 @@ void TraceLoggerDialog_t::updatePeriodic(void) if (logFile && logFileCbox->isChecked()) { - char line[256]; + //char line[256]; - while (recBufHead != recBufTail) - { - recBuf[recBufTail].convToText(line); + //while (recBufHead != recBufTail) + //{ + // recBuf[recBufTail].convToText(line); - fprintf(logFile, "%s\n", line); + // fprintf(logFile, "%s\n", line); - recBufTail = (recBufTail + 1) % recBufMax; - } + // recBufTail = (recBufTail + 1) % recBufMax; + //} } else { @@ -427,17 +433,17 @@ void TraceLoggerDialog_t::toggleLoggingOnOff(void) pushMsgToLogBuffer("Logging Finished"); startStopButton->setText(tr("Start Logging")); - if (logFile) - { - fclose(logFile); - logFile = NULL; - } + diskThread->requestInterruption(); + diskThread->quit(); + diskThread->wait(1000); } else { if (logFileCbox->isChecked()) { openLogFile(); + diskThread->start(); + msleep(100); } pushMsgToLogBuffer("Log Start"); startStopButton->setText(tr("Stop Logging")); @@ -1026,12 +1032,15 @@ static void pushToLogBuffer(traceRecord_t &rec) recBuf[recBufHead] = rec; recBufHead = (recBufHead + 1) % recBufMax; - if ( logFile != NULL ) + if ( logBuf ) { + logBuf[logBufHead] = rec; + logBufHead = (logBufHead + 1) % logBufMax; + if ( overrunWarningArmed ) { // Don't spam with buffer overrun warning messages, // we will print once if this happens. - if (recBufHead == recBufTail) + if (logBufHead == logBufTail) { if ( traceLogWindow ) { @@ -2157,3 +2166,88 @@ void QTraceLogView::paintEvent(QPaintEvent *event) } } //---------------------------------------------------- +TraceLogDiskThread_t::TraceLogDiskThread_t( QObject *parent ) + : QThread(parent) +{ + +} +//---------------------------------------------------- +TraceLogDiskThread_t::~TraceLogDiskThread_t(void) +{ + printf("Disk Thread Cleanup\n"); + if (logFile) + { + fclose(logFile); + logFile = NULL; + } + + if ( logBuf ) + { + free(logBuf); + logBuf = NULL; + } +} +//---------------------------------------------------- +void TraceLogDiskThread_t::run(void) +{ + char line[256]; + char buf[8192]; + int i,idx=0; + + printf("Trace Log Disk Start\n"); + + if ( logFile == NULL ) + { + return; + } + + if ( logBuf == NULL ) + { + size_t size; + + size = logBufMax * sizeof(traceRecord_t); + + logBufHead = logBufTail = 0; + + logBuf = (traceRecord_t *)malloc(size); + } + idx = 0; + + while ( !isInterruptionRequested() ) + { + while (logBufHead != logBufTail) + { + logBuf[logBufTail].convToText(line); + + i=0; + while ( line[i] != 0 ) + { + buf[idx] = line[i]; i++; idx++; + } + buf[idx] = '\n'; idx++; + + logBufTail = (logBufTail + 1) % logBufMax; + + if ( idx >= 4096 ) + { + fwrite( buf, idx, 1, logFile ); idx = 0; + } + } + SDL_Delay(10); + } + + if ( idx > 0 ) + { + fwrite( buf, idx, 1, logFile ); idx = 0; + } + + if (logFile) + { + fclose(logFile); + logFile = NULL; + } + + printf("Trace Log Disk Exit\n"); + emit finished(); +} +//---------------------------------------------------- diff --git a/src/drivers/Qt/TraceLogger.h b/src/drivers/Qt/TraceLogger.h index a44dd8c6..f14edca7 100644 --- a/src/drivers/Qt/TraceLogger.h +++ b/src/drivers/Qt/TraceLogger.h @@ -131,6 +131,23 @@ private slots: void ctxMenuAddSym(void); }; +class TraceLogDiskThread_t : public QThread +{ + Q_OBJECT + + protected: + void run( void ) override; + + public: + TraceLogDiskThread_t( QObject *parent = 0 ); + ~TraceLogDiskThread_t(void); + + private: + + signals: + void finished(void); +}; + class TraceLoggerDialog_t : public QDialog { Q_OBJECT @@ -139,6 +156,8 @@ public: TraceLoggerDialog_t(QWidget *parent = 0); ~TraceLoggerDialog_t(void); + TraceLogDiskThread_t *diskThread; + void showBufferWarning(void); protected: QTimer *updateTimer;