From 7d9ca913ec73c005ae9cd193426709dafb94e850 Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 19 Nov 2018 18:49:12 +0100 Subject: [PATCH] Attempt to fix race condition in glScope traces processing --- sdrgui/dsp/scopevis.cpp | 17 +++++++++++++---- sdrgui/gui/glscope.cpp | 25 +++++++++++++++++++++++-- sdrgui/gui/glscope.h | 5 +++++ 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/sdrgui/dsp/scopevis.cpp b/sdrgui/dsp/scopevis.cpp index 872d34f05..30c817191 100644 --- a/sdrgui/dsp/scopevis.cpp +++ b/sdrgui/dsp/scopevis.cpp @@ -607,15 +607,24 @@ int ScopeVis::processTraces(const SampleVector::const_iterator& cbegin, const Sa float traceTime = ((float) m_traceSize) / m_sampleRate; if (traceTime >= 1.0f) { // display continuously if trace time is 1 second or more - m_glScope->newTraces(&m_traces.m_traces[m_traces.currentBufferIndex()]); + m_glScope->newTraces(m_traces.m_traces, m_traces.currentBufferIndex()); } if (m_nbSamples == 0) // finished { - if (traceTime < 1.0f) { // display only at trace end if trace time is less than 1 second - m_glScope->newTraces(&m_traces.m_traces[m_traces.currentBufferIndex()]); + // display only at trace end if trace time is less than 1 second + if (traceTime < 1.0f) + { + if (m_glScope->getProcessingTraceIndex().load() < 0) { + m_glScope->newTraces(m_traces.m_traces, m_traces.currentBufferIndex()); + } } - m_traces.switchBuffer(); + + // switch to next buffer only if it is not being processed by the scope + if (m_glScope->getProcessingTraceIndex().load() != ((m_traces.currentBufferIndex() + 1) % 2)) { + m_traces.switchBuffer(); + } + return end - begin; // return remainder count } else diff --git a/sdrgui/gui/glscope.cpp b/sdrgui/gui/glscope.cpp index 76418b698..bdba1e1eb 100644 --- a/sdrgui/gui/glscope.cpp +++ b/sdrgui/gui/glscope.cpp @@ -30,6 +30,7 @@ GLScope::GLScope(QWidget* parent) : QGLWidget(parent), m_tracesData(0), m_traces(0), + m_processingTraceIndex(-1), m_bufferIndex(0), m_displayMode(DisplayX), m_dataChanged(false), @@ -112,6 +113,21 @@ void GLScope::newTraces(std::vector* traces) } } +void GLScope::newTraces(std::vector* traces, int traceIndex) +{ + if (traces->size() > 0) + { + if(!m_mutex.tryLock(2)) + return; + + m_processingTraceIndex.store(traceIndex); + m_traces = &traces[traceIndex]; + m_dataChanged = true; + + m_mutex.unlock(); + } +} + void GLScope::initializeGL() { QOpenGLContext *glCurrentContext = QOpenGLContext::currentContext(); @@ -176,11 +192,15 @@ void GLScope::resizeGL(int width, int height) void GLScope::paintGL() { - if(!m_mutex.tryLock(2)) + if (!m_mutex.tryLock(2)) + { + m_processingTraceIndex.store(-1); return; + } - if(m_configChanged) + if (m_configChanged) { applyConfig(); + } // qDebug("GLScope::paintGL: m_traceCounter: %d", m_traceCounter); // m_traceCounter = 0; @@ -920,6 +940,7 @@ void GLScope::paintGL() } // trace length > 0 } // XY mixed + polar display + m_processingTraceIndex.store(-1); m_mutex.unlock(); } diff --git a/sdrgui/gui/glscope.h b/sdrgui/gui/glscope.h index c33e91cc0..6120a2217 100644 --- a/sdrgui/gui/glscope.h +++ b/sdrgui/gui/glscope.h @@ -24,6 +24,8 @@ #include #include #include +#include + #include "dsp/dsptypes.h" #include "dsp/scopevis.h" #include "gui/scaleengine.h" @@ -54,6 +56,7 @@ public: void setTraces(std::vector* tracesData, std::vector* traces); void newTraces(std::vector* traces); + void newTraces(std::vector* traces, int traceIndex); int getSampleRate() const { return m_sampleRate; } int getTraceSize() const { return m_traceSize; } @@ -75,6 +78,7 @@ public: bool getDataChanged() const { return m_dataChanged; } DisplayMode getDisplayMode() const { return m_displayMode; } void setDisplayXYPoints(bool value) { m_displayXYPoints = value; } + const QAtomicInt& getProcessingTraceIndex() const { return m_processingTraceIndex; } signals: void sampleRateChanged(int); @@ -84,6 +88,7 @@ signals: private: std::vector *m_tracesData; std::vector *m_traces; + QAtomicInt m_processingTraceIndex; ScopeVis::TriggerData m_focusedTriggerData; //int m_traceCounter; uint32_t m_bufferIndex;