Added mutex for critical regions in the decode process

This commit is contained in:
Jordan Sherer 2019-11-17 01:21:07 -05:00
parent 3fb66f888c
commit 6d6212a8c0
4 changed files with 70 additions and 58 deletions

View File

@ -43,6 +43,8 @@ bool Detector::reset ()
void Detector::clear () void Detector::clear ()
{ {
QMutexLocker mutex(&m_lock);
#if JS8_RING_BUFFER #if JS8_RING_BUFFER
// set index to roughly where we are in time (1ms resolution) // set index to roughly where we are in time (1ms resolution)
qint64 now (DriftingDateTime::currentMSecsSinceEpoch ()); qint64 now (DriftingDateTime::currentMSecsSinceEpoch ());
@ -64,6 +66,8 @@ void Detector::clear ()
qint64 Detector::writeData (char const * data, qint64 maxSize) qint64 Detector::writeData (char const * data, qint64 maxSize)
{ {
QMutexLocker mutex(&m_lock);
int ns=secondInPeriod(); int ns=secondInPeriod();
if(ns < m_ns) { // When ns has wrapped around to zero, restart the buffers if(ns < m_ns) { // When ns has wrapped around to zero, restart the buffers
dec_data.params.kin = 0; dec_data.params.kin = 0;

View File

@ -2,6 +2,8 @@
#define DETECTOR_HPP__ #define DETECTOR_HPP__
#include "AudioDevice.hpp" #include "AudioDevice.hpp"
#include <QScopedArrayPointer> #include <QScopedArrayPointer>
#include <QMutex>
#include <QMutexLocker>
// //
// output device that distributes data in predefined chunks via a signal // output device that distributes data in predefined chunks via a signal
@ -24,6 +26,7 @@ public:
// //
Detector (unsigned frameRate, unsigned periodLengthInSeconds, unsigned downSampleFactor = 4u, QObject * parent = 0); Detector (unsigned frameRate, unsigned periodLengthInSeconds, unsigned downSampleFactor = 4u, QObject * parent = 0);
QMutex * getMutex(){ return &m_lock; }
unsigned period() const {return m_period;} unsigned period() const {return m_period;}
void setTRPeriod(unsigned p) {m_period=p;} void setTRPeriod(unsigned p) {m_period=p;}
bool reset () override; bool reset () override;
@ -55,6 +58,7 @@ private:
// data (a signals worth) at // data (a signals worth) at
// the input sample rate // the input sample rate
unsigned m_bufferPos; unsigned m_bufferPos;
QMutex m_lock;
}; };
#endif #endif

View File

@ -1496,8 +1496,8 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
// Don't block heartbeat's first run... // Don't block heartbeat's first run...
m_lastTxStartTime = DriftingDateTime::currentDateTimeUtc().addSecs(-300); m_lastTxStartTime = DriftingDateTime::currentDateTimeUtc().addSecs(-300);
// But do block the decoder's first run until the next transmit period // But do block the decoder's first run until 50% through next transmit period
m_lastTxStopTime = nextTransmitCycle(); m_lastTxStopTime = nextTransmitCycle().addSecs(-m_TRperiod/2);
int width = 75; int width = 75;
/* /*
@ -2687,7 +2687,7 @@ void MainWindow::dataSink(qint64 frames)
m_dateTime = DriftingDateTime::currentDateTimeUtc().toString ("yyyy-MMM-dd hh:mm"); m_dateTime = DriftingDateTime::currentDateTimeUtc().toString ("yyyy-MMM-dd hh:mm");
decode(); decode(k);
} }
QString MainWindow::save_wave_file (QString const& name, short const * data, int seconds, QString MainWindow::save_wave_file (QString const& name, short const * data, int seconds,
@ -3801,6 +3801,7 @@ void MainWindow::read_wav_file (QString const& fname)
m_nutc0=m_UTCdisk; m_nutc0=m_UTCdisk;
m_UTCdisk=fname.mid(i0+1,i1-i0-1).toInt(); m_UTCdisk=fname.mid(i0+1,i1-i0-1).toInt();
m_wav_future_watcher.setFuture (QtConcurrent::run ([this, fname] { m_wav_future_watcher.setFuture (QtConcurrent::run ([this, fname] {
QMutexLocker lock(m_detector->getMutex());
auto basename = fname.mid (fname.lastIndexOf ('/') + 1); auto basename = fname.mid (fname.lastIndexOf ('/') + 1);
auto pos = fname.indexOf (".wav", 0, Qt::CaseInsensitive); auto pos = fname.indexOf (".wav", 0, Qt::CaseInsensitive);
// global variables and threads do not mix well, this needs changing // global variables and threads do not mix well, this needs changing
@ -3841,7 +3842,6 @@ void MainWindow::read_wav_file (QString const& fname)
if(basename.mid(0,10)=="000000_000" && m_mode == "FT8") { if(basename.mid(0,10)=="000000_000" && m_mode == "FT8") {
dec_data.params.nutc=15*basename.mid(10,3).toInt(); dec_data.params.nutc=15*basename.mid(10,3).toInt();
} }
})); }));
} }
@ -3880,9 +3880,14 @@ void MainWindow::on_actionDecode_remaining_files_in_directory_triggered()
on_actionOpen_next_in_directory_triggered(); on_actionOpen_next_in_directory_triggered();
} }
void MainWindow::diskDat() //diskDat() void MainWindow::diskDat(){
{ QMutexLocker mutex(m_detector->getMutex());
if(dec_data.params.kin>0) {
if(dec_data.params.kin<=0) {
MessageBox::information_message(this, tr("No data read from disk. Wrong file format?"));
return;
}
int k; int k;
int kstep=m_FFTSize; int kstep=m_FFTSize;
m_diskData=true; m_diskData=true;
@ -3897,9 +3902,6 @@ void MainWindow::diskDat() //diskDat()
dataSink(k); dataSink(k);
qApp->processEvents(); //Update the waterfall qApp->processEvents(); //Update the waterfall
} }
} else {
MessageBox::information_message(this, tr("No data read from disk. Wrong file format?"));
}
} }
//Delete ../save/*.wav //Delete ../save/*.wav
@ -4036,9 +4038,8 @@ bool MainWindow::isDecodeReady(int submode, qint32 k, qint32 k0, qint32 *pCurren
* try decoding * try decoding
* @return true if the decoder was activated, false otherwise * @return true if the decoder was activated, false otherwise
*/ */
bool MainWindow::decode(){ bool MainWindow::decode(qint32 k){
static int k0 = 9999999; static int k0 = 9999999;
int k = dec_data.params.kin;
int kZero = k0; int kZero = k0;
k0 = k; k0 = k;
@ -4407,6 +4408,9 @@ bool MainWindow::decodeProcessQueue(qint32 *pSubmode){
* remove the lock file to start the decoding process * remove the lock file to start the decoding process
*/ */
void MainWindow::decodeStart(){ void MainWindow::decodeStart(){
// critical section
QMutexLocker mutex(m_detector->getMutex());
if(m_decoderBusy){ if(m_decoderBusy){
if(JS8_DEBUG_DECODE) qDebug() << "--> decoder cannot start...busy (busy flag)"; if(JS8_DEBUG_DECODE) qDebug() << "--> decoder cannot start...busy (busy flag)";
return; return;
@ -6466,7 +6470,7 @@ bool MainWindow::isMessageQueuedForTransmit(){
} }
bool MainWindow::isInDecodeDelayThreshold(int ms){ bool MainWindow::isInDecodeDelayThreshold(int ms){
if(m_lastTxStopTime.isNull()){ if(!m_lastTxStopTime.isValid() || m_lastTxStopTime.isNull()){
return false; return false;
} }

View File

@ -230,7 +230,7 @@ private slots:
void on_actionSpecial_mouse_commands_triggered(); void on_actionSpecial_mouse_commands_triggered();
void on_actionSolve_FreqCal_triggered(); void on_actionSolve_FreqCal_triggered();
void on_actionCopyright_Notice_triggered(); void on_actionCopyright_Notice_triggered();
bool decode(); bool decode(qint32 k);
bool isDecodeReady(int submode, qint32 k, qint32 k0, qint32 *pCurrentDecodeStart, qint32 *pNextDecodeStart, qint32 *pStart, qint32 *pSz, qint32 *pCycle); bool isDecodeReady(int submode, qint32 k, qint32 k0, qint32 *pCurrentDecodeStart, qint32 *pNextDecodeStart, qint32 *pStart, qint32 *pSz, qint32 *pCycle);
bool decodeEnqueueReady(qint32 k, qint32 k0); bool decodeEnqueueReady(qint32 k, qint32 k0);
bool decodeProcessQueue(qint32 *pSubmode); bool decodeProcessQueue(qint32 *pSubmode);