Move decoder process handling to separate thread to avoid exhaustuion

This commit is contained in:
Jordan Sherer 2019-11-19 10:39:27 -05:00
parent 2a320ddcdd
commit 1a03619a2f
4 changed files with 376 additions and 346 deletions

View File

@ -10,6 +10,7 @@
#define JS8_USE_IHSYM 0 // compute ihsym manually instead of from symspec #define JS8_USE_IHSYM 0 // compute ihsym manually instead of from symspec
#define JS8_RING_BUFFER 1 // use a ring buffer instead of clearing the decode frames #define JS8_RING_BUFFER 1 // use a ring buffer instead of clearing the decode frames
#define JS8_SINGLE_DECODE 0 // single submode decode per instantiation of the decoder #define JS8_SINGLE_DECODE 0 // single submode decode per instantiation of the decoder
#define JS8_DECODE_THREAD 1 // use a separate thread for decode process handling
#ifdef QT_DEBUG #ifdef QT_DEBUG
#define JS8_DEBUG_DECODE 1 // emit debug statements for the decode pipeline #define JS8_DEBUG_DECODE 1 // emit debug statements for the decode pipeline

View File

@ -170,7 +170,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
call flush(6) call flush(6)
ndecoded = my_js8a%decoded + my_js8b%decoded + my_js8c%decoded + my_js8e%decoded ndecoded = my_js8a%decoded + my_js8b%decoded + my_js8c%decoded + my_js8e%decoded
call sleep_msec(3000) !call sleep_msec(3000)
write(*,1010) ndecoded write(*,1010) ndecoded
1010 format('<DecodeFinished>',i4) 1010 format('<DecodeFinished>',i4)
call flush(6) call flush(6)

View File

@ -536,6 +536,9 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
, &m_WSPR_band_hopping, &WSPRBandHopping::set_tx_percent); , &m_WSPR_band_hopping, &WSPRBandHopping::set_tx_percent);
#endif #endif
// decoder queue handler
connect(this, &MainWindow::decodedLineReady, this, &MainWindow::processDecodedLine);
on_EraseButton_clicked (); on_EraseButton_clicked ();
QActionGroup* modeGroup = new QActionGroup(this); QActionGroup* modeGroup = new QActionGroup(this);
@ -1603,11 +1606,21 @@ void MainWindow::initDecoderSubprocess(){
if(JS8_DEBUG_DECODE) qDebug() << "decoder subprocess starting..."; if(JS8_DEBUG_DECODE) qDebug() << "decoder subprocess starting...";
auto proc = new QProcess(this); #if JS8_DECODE_THREAD
auto thread = new QThread(nullptr);
#endif
auto proc = new QProcess(nullptr);
connect(proc, &QProcess::readyReadStandardOutput, this, connect(proc, &QProcess::readyReadStandardOutput, this,
[this, proc](){ [this, proc](){
#if JS8_DECODE_THREAD
while(proc->canReadLine()){
emit decodedLineReady(proc->readLine());
}
#else
readFromStdout(proc); readFromStdout(proc);
#endif
}); });
connect(proc, static_cast<void (QProcess::*) (QProcess::ProcessError)> (&QProcess::error), connect(proc, static_cast<void (QProcess::*) (QProcess::ProcessError)> (&QProcess::error),
@ -1617,8 +1630,10 @@ void MainWindow::initDecoderSubprocess(){
connect(proc, static_cast<void (QProcess::*) (int, QProcess::ExitStatus)> (&QProcess::finished), connect(proc, static_cast<void (QProcess::*) (int, QProcess::ExitStatus)> (&QProcess::finished),
[this, proc] (int exitCode, QProcess::ExitStatus status) { [this, proc] (int exitCode, QProcess::ExitStatus status) {
#if JS8_DECODE_THREAD
proc->deleteLater(); proc->deleteLater();
proc->thread()->quit(); proc->thread()->quit();
#endif
subProcessFailed (proc, exitCode, status); subProcessFailed (proc, exitCode, status);
}); });
@ -1626,6 +1641,15 @@ void MainWindow::initDecoderSubprocess(){
proc->start(QDir::toNativeSeparators (m_appDir) + QDir::separator () + proc->start(QDir::toNativeSeparators (m_appDir) + QDir::separator () +
"js8", js8_args, QIODevice::ReadWrite | QIODevice::Unbuffered); "js8", js8_args, QIODevice::ReadWrite | QIODevice::Unbuffered);
#if JS8_DECODE_THREAD
if(JS8_DEBUG_DECODE) qDebug() << "decoder subprocess moving to new thread...";
// move process handling into its own thread
proc->moveToThread(thread);
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
thread->moveToThread(qApp->thread());
thread->start(QThread::HighPriority);
#endif
// create a process watcher looking for stdout read... // create a process watcher looking for stdout read...
// seems like we're starving the event loop or something? // seems like we're starving the event loop or something?
// auto watcher = new QTimer(proc); // auto watcher = new QTimer(proc);
@ -4681,7 +4705,13 @@ void MainWindow::readFromStdout(QProcess * proc) //r
} }
while(proc->canReadLine()) { while(proc->canReadLine()) {
QByteArray t = proc->readLine(); processDecodedLine(proc->readLine());
}
// See MainWindow::postDecode for displaying the latest decodes
}
void MainWindow::processDecodedLine(QByteArray t){
qDebug() << "JS8: " << QString(t); qDebug() << "JS8: " << QString(t);
bool bAvgMsg=false; bool bAvgMsg=false;
@ -4768,7 +4798,7 @@ void MainWindow::readFromStdout(QProcess * proc) //r
// skip if invalid // skip if invalid
if(!bValidFrame) { if(!bValidFrame) {
continue; return;
} }
ActivityDetail d = {}; ActivityDetail d = {};
@ -5025,9 +5055,6 @@ void MainWindow::readFromStdout(QProcess * proc) //r
} }
} }
#endif #endif
}
// See MainWindow::postDecode for displaying the latest decodes
} }
bool MainWindow::hasExistingMessageBufferToMe(int *pOffset){ bool MainWindow::hasExistingMessageBufferToMe(int *pOffset){

View File

@ -164,6 +164,7 @@ public slots:
void tryNotify(const QString &key); void tryNotify(const QString &key);
int rxThreshold(int submode); int rxThreshold(int submode);
int rxSnrThreshold(int submode); int rxSnrThreshold(int submode);
void processDecodedLine(QByteArray t);
protected: protected:
void keyPressEvent (QKeyEvent *) override; void keyPressEvent (QKeyEvent *) override;
@ -430,6 +431,7 @@ private slots:
void refreshTextDisplay(); void refreshTextDisplay();
private: private:
Q_SIGNAL void decodedLineReady(QByteArray t);
Q_SIGNAL void playNotification(const QString &name); Q_SIGNAL void playNotification(const QString &name);
Q_SIGNAL void initializeNotificationAudioOutputStream(const QAudioDeviceInfo &, unsigned, unsigned) const; Q_SIGNAL void initializeNotificationAudioOutputStream(const QAudioDeviceInfo &, unsigned, unsigned) const;
Q_SIGNAL void initializeAudioOutputStream (QAudioDeviceInfo, Q_SIGNAL void initializeAudioOutputStream (QAudioDeviceInfo,