From 37712c7a817cef5040cccf99aa74693e99153f97 Mon Sep 17 00:00:00 2001 From: vsonnier Date: Sun, 27 Aug 2017 12:39:28 +0200 Subject: [PATCH] Simplify SDRPostThread: no longer binding methods, directly use the true list of demodulators --- src/AppFrame.cpp | 2 +- src/CubicSDR.cpp | 13 +---- src/CubicSDR.h | 4 +- src/demod/DemodulatorInstance.cpp | 4 +- src/demod/DemodulatorWorkerThread.cpp | 5 +- src/forms/Bookmark/BookmarkView.cpp | 2 +- src/sdr/SDRPostThread.cpp | 80 ++++++++++----------------- src/sdr/SDRPostThread.h | 12 +--- src/visual/WaterfallCanvas.cpp | 4 +- 9 files changed, 44 insertions(+), 82 deletions(-) diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 10eb1bf..7f3b120 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -2273,7 +2273,7 @@ bool AppFrame::loadSession(std::string fileName) { } if (demodsLoaded.size()) { - wxGetApp().bindDemodulators(demodsLoaded); + wxGetApp().notifyDemodulatorsChanged(); } } // if l.rootNode()->hasAnother("demodulators") diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 019e38a..f4cb6aa 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -828,16 +828,9 @@ SDRThread *CubicSDR::getSDRThread() { } -void CubicSDR::bindDemodulator(DemodulatorInstancePtr demod) { - if (!demod) { - return; - } - sdrPostThread->bindDemodulator(demod); -} - -void CubicSDR::bindDemodulators(const std::vector& demods) { +void CubicSDR::notifyDemodulatorsChanged() { - sdrPostThread->bindDemodulators(demods); + sdrPostThread->notifyDemodulatorsChanged(); } long long CubicSDR::getSampleRate() { @@ -849,7 +842,7 @@ void CubicSDR::removeDemodulator(DemodulatorInstancePtr demod) { return; } demod->setActive(false); - sdrPostThread->removeDemodulator(demod); + sdrPostThread->notifyDemodulatorsChanged(); wxGetApp().getAppFrame()->notifyUpdateModemProperties(); } diff --git a/src/CubicSDR.h b/src/CubicSDR.h index 052f713..c167509 100644 --- a/src/CubicSDR.h +++ b/src/CubicSDR.h @@ -121,8 +121,8 @@ public: SDRPostThread *getSDRPostThread(); SDRThread *getSDRThread(); - void bindDemodulator(DemodulatorInstancePtr demod); - void bindDemodulators(const std::vector& demods); + void notifyDemodulatorsChanged(); + void removeDemodulator(DemodulatorInstancePtr demod); void setFrequencySnap(int snap); diff --git a/src/demod/DemodulatorInstance.cpp b/src/demod/DemodulatorInstance.cpp index ce4ee5f..1a96089 100644 --- a/src/demod/DemodulatorInstance.cpp +++ b/src/demod/DemodulatorInstance.cpp @@ -85,10 +85,10 @@ DemodulatorInstance::DemodulatorInstance() { DemodulatorInstance::~DemodulatorInstance() { //now that DemodulatorInstance are managed through shared_ptr, we - //should enter here ONLY when it is no longer used by any piece of code, anywahere. + //should enter here ONLY when it is no longer used by any piece of code, anywhere. //so active wait on IsTerminated(), then die. #define TERMINATION_SPIN_WAIT_MS (20) -#define MAX_WAIT_FOR_TERMINATION_MS (1000.0) +#define MAX_WAIT_FOR_TERMINATION_MS (3000.0) //this is a stupid busy plus sleep loop int nbCyclesToWait = (MAX_WAIT_FOR_TERMINATION_MS / TERMINATION_SPIN_WAIT_MS) + 1; int currentCycle = 0; diff --git a/src/demod/DemodulatorWorkerThread.cpp b/src/demod/DemodulatorWorkerThread.cpp index 00010f1..a2bd35d 100644 --- a/src/demod/DemodulatorWorkerThread.cpp +++ b/src/demod/DemodulatorWorkerThread.cpp @@ -9,9 +9,6 @@ //50 ms #define HEARTBEAT_CHECK_PERIOD_MICROS (50 * 1000) -//1s -#define MAX_BLOCKING_DURATION_MICROS (1000 * 1000) - DemodulatorWorkerThread::DemodulatorWorkerThread() : IOThread(), commandQueue(nullptr), resultQueue(nullptr), cModem(nullptr), cModemKit(nullptr) { } @@ -111,7 +108,7 @@ void DemodulatorWorkerThread::run() { result.modemName = cModemName; //VSO: blocking push - resultQueue->push(result, MAX_BLOCKING_DURATION_MICROS, "resultQueue"); + resultQueue->push(result); } } // std::cout << "Demodulator worker thread done." << std::endl; diff --git a/src/forms/Bookmark/BookmarkView.cpp b/src/forms/Bookmark/BookmarkView.cpp index b06076a..4cb9888 100644 --- a/src/forms/Bookmark/BookmarkView.cpp +++ b/src/forms/Bookmark/BookmarkView.cpp @@ -845,7 +845,7 @@ void BookmarkView::activateBookmark(BookmarkEntryPtr bmEnt) { matchingDemod = wxGetApp().getDemodMgr().loadInstance(bmEnt->node); matchingDemod->run(); - wxGetApp().bindDemodulator(matchingDemod); + wxGetApp().notifyDemodulatorsChanged(); } matchingDemod->setActive(true); diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index 10c7f04..af5471d 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -36,41 +36,12 @@ SDRPostThread::SDRPostThread() : IOThread(), buffers("SDRPostThreadBuffers"), vi SDRPostThread::~SDRPostThread() { } -void SDRPostThread::bindDemodulator(DemodulatorInstancePtr demod) { - - std::lock_guard < std::mutex > lock(busy_demod); - - demodulators.push_back(demod); +void SDRPostThread::notifyDemodulatorsChanged() { + doRefresh.store(true); } -void SDRPostThread::bindDemodulators(const std::vector& demods) { - - std::lock_guard < std::mutex > lock(busy_demod); - - for (auto di : demods) { - demodulators.push_back(di); - doRefresh.store(true); - } -} - -void SDRPostThread::removeDemodulator(DemodulatorInstancePtr demod) { - if (!demod) { - return; - } - - std::lock_guard < std::mutex > lock(busy_demod); - - auto it = std::find(demodulators.begin(), demodulators.end(), demod); - - if (it != demodulators.end()) { - demodulators.erase(it); - doRefresh.store(true); - } - -} - void SDRPostThread::initPFBChannelizer() { // std::cout << "Initializing post-process FIR polyphase filterbank channelizer with " << numChannels << " channels." << std::endl; if (channelizer) { @@ -93,6 +64,9 @@ void SDRPostThread::updateActiveDemodulators() { long long centerFreq = wxGetApp().getFrequency(); + //retreive the current list of demodulators: + auto demodulators = wxGetApp().getDemodMgr().getDemodulators(); + for (auto demod : demodulators) { // not in range? @@ -189,9 +163,8 @@ void SDRPostThread::run() { if (!iqDataInQueue->pop(data_in, HEARTBEAT_CHECK_PERIOD_MICROS)) { continue; } - // std::lock_guard < std::mutex > lock(data_in->m_mutex); - - std::lock_guard < std::mutex > lock(busy_demod); + + bool doUpdate = false; if (data_in && data_in->data.size()) { if(data_in->numChannels > 1) { @@ -200,8 +173,7 @@ void SDRPostThread::run() { runSingleCH(data_in.get()); } } - - bool doUpdate = false; + for (size_t j = 0; j < nRunDemods; j++) { DemodulatorInstancePtr demod = runDemods[j]; if (abs(frequency - demod->getFrequency()) > (sampleRate / 2)) { @@ -210,7 +182,7 @@ void SDRPostThread::run() { } //Only update the list of demodulators here - if (doUpdate) { + if (doUpdate || doRefresh) { updateActiveDemodulators(); } } //end while @@ -259,9 +231,9 @@ void SDRPostThread::runSingleCH(SDRThreadIQData *data_in) { } size_t refCount = nRunDemods; - bool doIQDataOut = (iqDataOutQueue != NULL && !iqDataOutQueue->full()); + bool doIQDataOut = (iqDataOutQueue != nullptr && !iqDataOutQueue->full()); bool doDemodVisOut = (nRunDemods && iqActiveDemodVisualQueue != NULL && !iqActiveDemodVisualQueue->full()); - bool doVisOut = (iqVisualQueue != NULL && !iqVisualQueue->full()); + bool doVisOut = (iqVisualQueue != nullptr && !iqVisualQueue->full()); if (doIQDataOut) { refCount++; @@ -290,22 +262,26 @@ void SDRPostThread::runSingleCH(SDRThreadIQData *data_in) { if (doDemodVisOut) { //VSO: blocking push - iqActiveDemodVisualQueue->push(demodDataOut, MAX_BLOCKING_DURATION_MICROS, "runSingleCH() iqActiveDemodVisualQueue"); + iqActiveDemodVisualQueue->push(demodDataOut); } if (doIQDataOut) { //VSO: blocking push - iqDataOutQueue->push(demodDataOut, MAX_BLOCKING_DURATION_MICROS,"runSingleCH() iqDataOutQueue"); + iqDataOutQueue->push(demodDataOut); } if (doVisOut) { //VSO: blocking push - iqVisualQueue->push(demodDataOut, MAX_BLOCKING_DURATION_MICROS, "runSingleCH() iqVisualQueue"); + iqVisualQueue->push(demodDataOut); } for (size_t i = 0; i < nRunDemods; i++) { - //VSO: blocking push - runDemods[i]->getIQInputDataPipe()->push(demodDataOut, MAX_BLOCKING_DURATION_MICROS, "runSingleCH() runDemods[i]->getIQInputDataPipe()"); + //VSO: timed-push + if (!runDemods[i]->getIQInputDataPipe()->push(demodDataOut, MAX_BLOCKING_DURATION_MICROS, "runSingleCH() runDemods[i]->getIQInputDataPipe()")) { + //some runDemods are no longer there, bail out from runSingleCH() entirely. + doRefresh = true; + return; + } } } } @@ -342,11 +318,11 @@ void SDRPostThread::runPFBCH(SDRThreadIQData *data_in) { iqDataOut->data.assign(data_in->data.begin(), data_in->data.begin() + dataSize); //VSO: blocking push - iqDataOutQueue->push(iqDataOut, MAX_BLOCKING_DURATION_MICROS, "runPFBCH() iqDataOutQueue"); + iqDataOutQueue->push(iqDataOut); if (doVis) { //VSO: blocking push - iqVisualQueue->push(iqDataOut, MAX_BLOCKING_DURATION_MICROS, "runPFBCH() iqVisualQueue"); + iqVisualQueue->push(iqDataOut); } } @@ -442,16 +418,20 @@ void SDRPostThread::runPFBCH(SDRThreadIQData *data_in) { if (doDemodVis) { //VSO: blocking push - iqActiveDemodVisualQueue->push(demodDataOut, MAX_BLOCKING_DURATION_MICROS, "runPFBCH() iqActiveDemodVisualQueue"); + iqActiveDemodVisualQueue->push(demodDataOut); } for (size_t j = 0; j < nRunDemods; j++) { if (demodChannel[j] == i) { - //VSO: blocking push - runDemods[j]->getIQInputDataPipe()->push(demodDataOut, MAX_BLOCKING_DURATION_MICROS, "runPFBCH() demod->getIQInputDataPipe()"); + //VSO: timed- push + if (!runDemods[j]->getIQInputDataPipe()->push(demodDataOut, MAX_BLOCKING_DURATION_MICROS, "runPFBCH() runDemods[j]->getIQInputDataPipe()")) { + //Some runDemods are no longer there, bail out from runPFBCH() entirely. + doRefresh = true; + return; + } } - } + } //end for } } } diff --git a/src/sdr/SDRPostThread.h b/src/sdr/SDRPostThread.h index 081b585..99a5e16 100644 --- a/src/sdr/SDRPostThread.h +++ b/src/sdr/SDRPostThread.h @@ -11,10 +11,8 @@ public: SDRPostThread(); ~SDRPostThread(); - void bindDemodulator(DemodulatorInstancePtr demod); - void bindDemodulators(const std::vector& demods); - void removeDemodulator(DemodulatorInstancePtr demod); - + void notifyDemodulatorsChanged(); + virtual void run(); virtual void terminate(); @@ -27,12 +25,6 @@ protected: DemodulatorThreadInputQueuePtr iqDataOutQueue; DemodulatorThreadInputQueuePtr iqVisualQueue; DemodulatorThreadInputQueuePtr iqActiveDemodVisualQueue; - - //protects access to demodulators lists and such - std::mutex busy_demod; - std::vector demodulators; - - private: diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index b7b23c7..9a36d2f 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -729,7 +729,7 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) { demod->writeModemSettings(mgr->getLastModemSettings(mgr->getLastDemodulatorType())); demod->run(); - wxGetApp().bindDemodulator(demod); + wxGetApp().notifyDemodulatorsChanged(); DemodulatorThread::releaseSquelchLock(nullptr); } @@ -829,7 +829,7 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) { demod->run(); - wxGetApp().bindDemodulator(demod); + wxGetApp().notifyDemodulatorsChanged(); } if (demod == NULL) {