1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-09-21 12:26:34 -04:00

Fixed threading model for DSPDeviceSinkEngine plus other fixes. Part of #2159

This commit is contained in:
f4exb 2024-08-18 13:37:27 +02:00 committed by Edouard Griffiths
parent 75d40c8b68
commit aca4a53513
5 changed files with 51 additions and 74 deletions

View File

@ -28,7 +28,7 @@
#include "dsp/dspcommands.h" #include "dsp/dspcommands.h"
DSPDeviceSinkEngine::DSPDeviceSinkEngine(uint32_t uid, QObject* parent) : DSPDeviceSinkEngine::DSPDeviceSinkEngine(uint32_t uid, QObject* parent) :
QThread(parent), QObject(parent),
m_uid(uid), m_uid(uid),
m_state(StNotStarted), m_state(StNotStarted),
m_deviceSampleSink(nullptr), m_deviceSampleSink(nullptr),
@ -41,8 +41,6 @@ DSPDeviceSinkEngine::DSPDeviceSinkEngine(uint32_t uid, QObject* parent) :
{ {
setState(StIdle); setState(StIdle);
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection); connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
moveToThread(this);
} }
DSPDeviceSinkEngine::~DSPDeviceSinkEngine() DSPDeviceSinkEngine::~DSPDeviceSinkEngine()
@ -59,29 +57,6 @@ void DSPDeviceSinkEngine::setState(State state)
} }
} }
void DSPDeviceSinkEngine::run()
{
qDebug() << "DSPDeviceSinkEngine::run";
setState(StIdle);
exec();
}
void DSPDeviceSinkEngine::start()
{
qDebug() << "DSPDeviceSinkEngine::start";
QThread::start();
}
void DSPDeviceSinkEngine::stop()
{
qDebug() << "DSPDeviceSinkEngine::stop";
gotoIdle();
setState(StNotStarted);
QThread::exit();
// DSPExit cmd;
// m_syncMessenger.sendWait(cmd);
}
bool DSPDeviceSinkEngine::initGeneration() bool DSPDeviceSinkEngine::initGeneration()
{ {
qDebug() << "DSPDeviceSinkEngine::initGeneration"; qDebug() << "DSPDeviceSinkEngine::initGeneration";
@ -101,7 +76,7 @@ bool DSPDeviceSinkEngine::startGeneration()
void DSPDeviceSinkEngine::stopGeneration() void DSPDeviceSinkEngine::stopGeneration()
{ {
qDebug() << "DSPDeviceSinkEngine::stopGeneration"; qDebug() << "DSPDeviceSinkEngine::stopGeneration";
DSPGenerationStop *cmd = new DSPGenerationStop(); auto *cmd = new DSPGenerationStop();
getInputMessageQueue()->push(cmd); getInputMessageQueue()->push(cmd);
} }
@ -122,7 +97,7 @@ void DSPDeviceSinkEngine::setSinkSequence(int sequence)
void DSPDeviceSinkEngine::addChannelSource(BasebandSampleSource* source) void DSPDeviceSinkEngine::addChannelSource(BasebandSampleSource* source)
{ {
qDebug() << "DSPDeviceSinkEngine::addChannelSource: " << source->getSourceName().toStdString().c_str(); qDebug() << "DSPDeviceSinkEngine::addChannelSource: " << source->getSourceName().toStdString().c_str();
DSPAddBasebandSampleSource *cmd = new DSPAddBasebandSampleSource(source); auto *cmd = new DSPAddBasebandSampleSource(source);
getInputMessageQueue()->push(cmd); getInputMessageQueue()->push(cmd);
} }
@ -167,7 +142,10 @@ void DSPDeviceSinkEngine::workSampleFifo()
} }
SampleVector& data = sourceFifo->getData(); SampleVector& data = sourceFifo->getData();
unsigned int iPart1Begin, iPart1End, iPart2Begin, iPart2End; unsigned int iPart1Begin;
unsigned int iPart1End;
unsigned int iPart2Begin;
unsigned int iPart2End;
unsigned int remainder = sourceFifo->remainder(); unsigned int remainder = sourceFifo->remainder();
while ((remainder > 0) && (m_inputMessageQueue.size() == 0)) while ((remainder > 0) && (m_inputMessageQueue.size() == 0))
@ -208,7 +186,7 @@ void DSPDeviceSinkEngine::workSamples(SampleVector& data, unsigned int iBegin, u
else else
{ {
m_sourceSampleBuffer.allocate(nbSamples); m_sourceSampleBuffer.allocate(nbSamples);
SampleVector::iterator sBegin = m_sourceSampleBuffer.m_vector.begin(); auto sBegin = m_sourceSampleBuffer.m_vector.begin();
BasebandSampleSources::const_iterator srcIt = m_basebandSampleSources.begin(); BasebandSampleSources::const_iterator srcIt = m_basebandSampleSources.begin();
BasebandSampleSource *source = *srcIt; BasebandSampleSource *source = *srcIt;
source->pull(begin, nbSamples); source->pull(begin, nbSamples);
@ -309,7 +287,7 @@ DSPDeviceSinkEngine::State DSPDeviceSinkEngine::gotoInit()
m_sampleRate = m_deviceSampleSink->getSampleRate(); m_sampleRate = m_deviceSampleSink->getSampleRate();
qDebug() << "DSPDeviceSinkEngine::gotoInit: " qDebug() << "DSPDeviceSinkEngine::gotoInit: "
<< " m_deviceDescription: " << m_deviceDescription.toStdString().c_str() << " m_deviceDescription: " << m_deviceDescription.toStdString().c_str()
<< " sampleRate: " << m_sampleRate << " sampleRate: " << m_sampleRate
<< " centerFrequency: " << m_centerFrequency; << " centerFrequency: " << m_centerFrequency;
@ -328,7 +306,7 @@ DSPDeviceSinkEngine::State DSPDeviceSinkEngine::gotoInit()
// pass data to listeners // pass data to listeners
if (m_deviceSampleSink->getMessageQueueToGUI()) if (m_deviceSampleSink->getMessageQueueToGUI())
{ {
DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy for the output queue auto* rep = new DSPSignalNotification(notif); // make a copy for the output queue
m_deviceSampleSink->getMessageQueueToGUI()->push(rep); m_deviceSampleSink->getMessageQueueToGUI()->push(rep);
} }
@ -413,7 +391,7 @@ void DSPDeviceSinkEngine::handleSetSink(DeviceSampleSink*)
void DSPDeviceSinkEngine::handleData() void DSPDeviceSinkEngine::handleData()
{ {
if (m_state == StRunning) { if (m_state == StRunning) {
workSampleFifo(); workSampleFifo();
} }
} }
@ -421,7 +399,7 @@ bool DSPDeviceSinkEngine::handleMessage(const Message& message)
{ {
if (DSPSignalNotification::match(message)) if (DSPSignalNotification::match(message))
{ {
const DSPSignalNotification& notif = (const DSPSignalNotification&) message; auto& notif = (const DSPSignalNotification&) message;
// update DSP values // update DSP values

View File

@ -22,7 +22,7 @@
#ifndef SDRBASE_DSP_DSPDEVICESINKENGINE_H_ #ifndef SDRBASE_DSP_DSPDEVICESINKENGINE_H_
#define SDRBASE_DSP_DSPDEVICESINKENGINE_H_ #define SDRBASE_DSP_DSPDEVICESINKENGINE_H_
#include <QThread> #include <QObject>
#include <QTimer> #include <QTimer>
#include <QMutex> #include <QMutex>
#include <QWaitCondition> #include <QWaitCondition>
@ -40,7 +40,7 @@ class DeviceSampleSink;
class BasebandSampleSource; class BasebandSampleSource;
class BasebandSampleSink; class BasebandSampleSink;
class SDRBASE_API DSPDeviceSinkEngine : public QThread { class SDRBASE_API DSPDeviceSinkEngine : public QObject {
Q_OBJECT Q_OBJECT
public: public:
@ -52,16 +52,13 @@ public:
StError //!< engine is in error StError //!< engine is in error
}; };
DSPDeviceSinkEngine(uint32_t uid, QObject* parent = NULL); DSPDeviceSinkEngine(uint32_t uid, QObject* parent = nullptr);
~DSPDeviceSinkEngine(); ~DSPDeviceSinkEngine();
uint32_t getUID() const { return m_uid; } uint32_t getUID() const { return m_uid; }
MessageQueue* getInputMessageQueue() { return &m_inputMessageQueue; } MessageQueue* getInputMessageQueue() { return &m_inputMessageQueue; }
void start(); //!< This thread start
void stop(); //!< This thread stop
bool initGeneration(); //!< Initialize generation sequence bool initGeneration(); //!< Initialize generation sequence
bool startGeneration(); //!< Start generation sequence bool startGeneration(); //!< Start generation sequence
void stopGeneration(); //!< Stop generation sequence void stopGeneration(); //!< Stop generation sequence
@ -106,7 +103,6 @@ private:
bool m_realElseComplex; bool m_realElseComplex;
unsigned int m_sumIndex; //!< channel index when summing channels unsigned int m_sumIndex; //!< channel index when summing channels
void run();
void workSampleFifo(); //!< transfer samples from baseband sources to sink if in running state void workSampleFifo(); //!< transfer samples from baseband sources to sink if in running state
void workSamples(SampleVector& data, unsigned int iBegin, unsigned int iEnd); void workSamples(SampleVector& data, unsigned int iBegin, unsigned int iEnd);

View File

@ -111,24 +111,45 @@ void DSPEngine::removeLastDeviceSourceEngine()
DSPDeviceSinkEngine *DSPEngine::addDeviceSinkEngine() DSPDeviceSinkEngine *DSPEngine::addDeviceSinkEngine()
{ {
m_deviceSinkEngines.push_back(new DSPDeviceSinkEngine(m_deviceSinkEnginesUIDSequence)); auto *deviceSinkEngine = new DSPDeviceSinkEngine(m_deviceSinkEnginesUIDSequence);
auto *deviceThread = new QThread();
m_deviceSinkEnginesUIDSequence++; m_deviceSinkEnginesUIDSequence++;
m_deviceEngineReferences.push_back(DeviceEngineReference{1, nullptr, m_deviceSinkEngines.back(), nullptr, nullptr}); m_deviceSinkEngines.push_back(deviceSinkEngine);
return m_deviceSinkEngines.back(); m_deviceEngineReferences.push_back(DeviceEngineReference{1, nullptr, m_deviceSinkEngines.back(), nullptr, deviceThread});
deviceSinkEngine->moveToThread(deviceThread);
QObject::connect(
deviceThread,
&QThread::finished,
deviceSinkEngine,
&QObject::deleteLater
);
QObject::connect(
deviceThread,
&QThread::finished,
deviceThread,
&QThread::deleteLater
);
deviceThread->start();
return deviceSinkEngine;
} }
void DSPEngine::removeLastDeviceSinkEngine() void DSPEngine::removeLastDeviceSinkEngine()
{ {
if (m_deviceSinkEngines.size() > 0) if (!m_deviceSinkEngines.empty())
{ {
DSPDeviceSinkEngine *lastDeviceEngine = m_deviceSinkEngines.back(); const DSPDeviceSinkEngine *lastDeviceEngine = m_deviceSinkEngines.back();
delete lastDeviceEngine;
m_deviceSinkEngines.pop_back(); m_deviceSinkEngines.pop_back();
for (int i = 0; i < m_deviceEngineReferences.size(); i++) for (int i = 0; i < m_deviceEngineReferences.size(); i++)
{ {
if (m_deviceEngineReferences[i].m_deviceSinkEngine == lastDeviceEngine) if (m_deviceEngineReferences[i].m_deviceSinkEngine == lastDeviceEngine)
{ {
QThread* deviceThread = m_deviceEngineReferences[i].m_thread;
deviceThread->exit();
deviceThread->wait();
m_deviceEngineReferences.removeAt(i); m_deviceEngineReferences.removeAt(i);
break; break;
} }
@ -201,7 +222,9 @@ void DSPEngine::removeDeviceEngineAt(int deviceIndex)
else if (m_deviceEngineReferences[deviceIndex].m_deviceEngineType == 1) // sink else if (m_deviceEngineReferences[deviceIndex].m_deviceEngineType == 1) // sink
{ {
DSPDeviceSinkEngine *deviceEngine = m_deviceEngineReferences[deviceIndex].m_deviceSinkEngine; DSPDeviceSinkEngine *deviceEngine = m_deviceEngineReferences[deviceIndex].m_deviceSinkEngine;
delete deviceEngine; QThread *deviceThread = m_deviceEngineReferences[deviceIndex].m_thread;
deviceThread->exit();
deviceThread->wait();
m_deviceSinkEngines.removeAll(deviceEngine); m_deviceSinkEngines.removeAll(deviceEngine);
} }
else if (m_deviceEngineReferences[deviceIndex].m_deviceEngineType == 2) // MIMO else if (m_deviceEngineReferences[deviceIndex].m_deviceEngineType == 2) // MIMO

View File

@ -565,7 +565,6 @@ void MainWindow::sampleSourceCreate(
void MainWindow::sampleSinkAdd(Workspace *deviceWorkspace, Workspace *spectrumWorkspace, int deviceIndex) void MainWindow::sampleSinkAdd(Workspace *deviceWorkspace, Workspace *spectrumWorkspace, int deviceIndex)
{ {
DSPDeviceSinkEngine *dspDeviceSinkEngine = m_dspEngine->addDeviceSinkEngine(); DSPDeviceSinkEngine *dspDeviceSinkEngine = m_dspEngine->addDeviceSinkEngine();
dspDeviceSinkEngine->start();
uint dspDeviceSinkEngineUID = dspDeviceSinkEngine->getUID(); uint dspDeviceSinkEngineUID = dspDeviceSinkEngine->getUID();
char uidCStr[16]; char uidCStr[16];
@ -993,7 +992,6 @@ void MainWindow::removeDeviceSet(int deviceSetIndex)
if (deviceUISet->m_deviceSourceEngine) // source device if (deviceUISet->m_deviceSourceEngine) // source device
{ {
DSPDeviceSourceEngine *deviceEngine = deviceUISet->m_deviceSourceEngine; DSPDeviceSourceEngine *deviceEngine = deviceUISet->m_deviceSourceEngine;
deviceEngine->stopAcquistion();
deviceEngine->removeSink(deviceUISet->m_spectrumVis); deviceEngine->removeSink(deviceUISet->m_spectrumVis);
// deletes old UI and core object // deletes old UI and core object
@ -1015,7 +1013,6 @@ void MainWindow::removeDeviceSet(int deviceSetIndex)
else if (deviceUISet->m_deviceSinkEngine) // sink device else if (deviceUISet->m_deviceSinkEngine) // sink device
{ {
DSPDeviceSinkEngine *deviceEngine = deviceUISet->m_deviceSinkEngine; DSPDeviceSinkEngine *deviceEngine = deviceUISet->m_deviceSinkEngine;
deviceEngine->stopGeneration();
deviceEngine->removeSpectrumSink(deviceUISet->m_spectrumVis); deviceEngine->removeSpectrumSink(deviceUISet->m_spectrumVis);
// deletes old UI and output object // deletes old UI and output object
@ -1023,24 +1020,19 @@ void MainWindow::removeDeviceSet(int deviceSetIndex)
deviceUISet->m_deviceAPI->getSampleSink()->setMessageQueueToGUI(nullptr); // have sink stop sending messages to the GUI deviceUISet->m_deviceAPI->getSampleSink()->setMessageQueueToGUI(nullptr); // have sink stop sending messages to the GUI
deviceUISet->m_deviceGUI->destroy(); deviceUISet->m_deviceGUI->destroy();
deviceUISet->m_deviceAPI->resetSamplingDeviceId(); deviceUISet->m_deviceAPI->resetSamplingDeviceId();
deviceUISet->m_deviceAPI->getPluginInterface()->deleteSampleSinkPluginInstanceOutput(
deviceUISet->m_deviceAPI->getSampleSink());
deviceUISet->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists deviceUISet->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists
DeviceAPI *sinkAPI = deviceUISet->m_deviceAPI;
delete deviceUISet;
deviceEngine->stop();
m_dspEngine->removeDeviceEngineAt(deviceSetIndex); m_dspEngine->removeDeviceEngineAt(deviceSetIndex);
DeviceEnumerator::instance()->removeTxSelection(deviceSetIndex); DeviceEnumerator::instance()->removeTxSelection(deviceSetIndex);
DeviceAPI *sinkAPI = deviceUISet->m_deviceAPI;
delete deviceUISet;
delete sinkAPI->getSampleSink();
delete sinkAPI; delete sinkAPI;
} }
else if (deviceUISet->m_deviceMIMOEngine) // MIMO device else if (deviceUISet->m_deviceMIMOEngine) // MIMO device
{ {
DSPDeviceMIMOEngine *deviceEngine = deviceUISet->m_deviceMIMOEngine; DSPDeviceMIMOEngine *deviceEngine = deviceUISet->m_deviceMIMOEngine;
deviceEngine->stopProcess(1); // Tx side
deviceEngine->stopProcess(0); // Rx side
deviceEngine->removeSpectrumSink(deviceUISet->m_spectrumVis); deviceEngine->removeSpectrumSink(deviceUISet->m_spectrumVis);
// deletes old UI and output object // deletes old UI and output object
@ -1096,7 +1088,6 @@ void MainWindow::removeLastDeviceSet()
if (m_deviceUIs.back()->m_deviceSourceEngine) // source tab if (m_deviceUIs.back()->m_deviceSourceEngine) // source tab
{ {
DSPDeviceSourceEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceSourceEngine; DSPDeviceSourceEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceSourceEngine;
lastDeviceEngine->stopAcquistion();
lastDeviceEngine->removeSink(m_deviceUIs.back()->m_spectrumVis); lastDeviceEngine->removeSink(m_deviceUIs.back()->m_spectrumVis);
// deletes old UI and input object // deletes old UI and input object
@ -1116,7 +1107,6 @@ void MainWindow::removeLastDeviceSet()
else if (m_deviceUIs.back()->m_deviceSinkEngine) // sink tab else if (m_deviceUIs.back()->m_deviceSinkEngine) // sink tab
{ {
DSPDeviceSinkEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceSinkEngine; DSPDeviceSinkEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceSinkEngine;
lastDeviceEngine->stopGeneration();
lastDeviceEngine->removeSpectrumSink(m_deviceUIs.back()->m_spectrumVis); lastDeviceEngine->removeSpectrumSink(m_deviceUIs.back()->m_spectrumVis);
// deletes old UI and output object // deletes old UI and output object
@ -1136,8 +1126,6 @@ void MainWindow::removeLastDeviceSet()
else if (m_deviceUIs.back()->m_deviceMIMOEngine) // MIMO tab else if (m_deviceUIs.back()->m_deviceMIMOEngine) // MIMO tab
{ {
DSPDeviceMIMOEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceMIMOEngine; DSPDeviceMIMOEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceMIMOEngine;
lastDeviceEngine->stopProcess(1); // Tx side
lastDeviceEngine->stopProcess(0); // Rx side
lastDeviceEngine->removeSpectrumSink(m_deviceUIs.back()->m_spectrumVis); lastDeviceEngine->removeSpectrumSink(m_deviceUIs.back()->m_spectrumVis);
// deletes old UI and output object // deletes old UI and output object

View File

@ -270,7 +270,6 @@ void MainServer::applySettings()
void MainServer::addSinkDevice() void MainServer::addSinkDevice()
{ {
DSPDeviceSinkEngine *dspDeviceSinkEngine = m_dspEngine->addDeviceSinkEngine(); DSPDeviceSinkEngine *dspDeviceSinkEngine = m_dspEngine->addDeviceSinkEngine();
dspDeviceSinkEngine->start();
uint dspDeviceSinkEngineUID = dspDeviceSinkEngine->getUID(); uint dspDeviceSinkEngineUID = dspDeviceSinkEngine->getUID();
char uidCStr[16]; char uidCStr[16];
@ -398,7 +397,6 @@ void MainServer::removeLastDevice()
if (m_mainCore->m_deviceSets.back()->m_deviceSourceEngine) // source set if (m_mainCore->m_deviceSets.back()->m_deviceSourceEngine) // source set
{ {
DSPDeviceSourceEngine *lastDeviceEngine = m_mainCore->m_deviceSets.back()->m_deviceSourceEngine; DSPDeviceSourceEngine *lastDeviceEngine = m_mainCore->m_deviceSets.back()->m_deviceSourceEngine;
lastDeviceEngine->stopAcquistion();
// deletes old UI and input object // deletes old UI and input object
m_mainCore->m_deviceSets.back()->freeChannels(); // destroys the channel instances m_mainCore->m_deviceSets.back()->freeChannels(); // destroys the channel instances
@ -415,28 +413,22 @@ void MainServer::removeLastDevice()
else if (m_mainCore->m_deviceSets.back()->m_deviceSinkEngine) // sink set else if (m_mainCore->m_deviceSets.back()->m_deviceSinkEngine) // sink set
{ {
DSPDeviceSinkEngine *lastDeviceEngine = m_mainCore->m_deviceSets.back()->m_deviceSinkEngine; DSPDeviceSinkEngine *lastDeviceEngine = m_mainCore->m_deviceSets.back()->m_deviceSinkEngine;
lastDeviceEngine->stopGeneration();
// deletes old UI and output object // deletes old UI and output object
m_mainCore->m_deviceSets.back()->freeChannels(); m_mainCore->m_deviceSets.back()->freeChannels();
m_mainCore->m_deviceSets.back()->m_deviceAPI->resetSamplingDeviceId(); m_mainCore->m_deviceSets.back()->m_deviceAPI->resetSamplingDeviceId();
m_mainCore->m_deviceSets.back()->m_deviceAPI->getPluginInterface()->deleteSampleSinkPluginInstanceOutput(
m_mainCore->m_deviceSets.back()->m_deviceAPI->getSampleSink());
m_mainCore->m_deviceSets.back()->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists m_mainCore->m_deviceSets.back()->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists
m_dspEngine->removeLastDeviceSinkEngine();
DeviceAPI *sinkAPI = m_mainCore->m_deviceSets.back()->m_deviceAPI; DeviceAPI *sinkAPI = m_mainCore->m_deviceSets.back()->m_deviceAPI;
delete m_mainCore->m_deviceSets.back(); delete m_mainCore->m_deviceSets.back();
delete sinkAPI->getSampleSink();
lastDeviceEngine->stop();
m_dspEngine->removeLastDeviceSinkEngine();
delete sinkAPI; delete sinkAPI;
} }
else if (m_mainCore->m_deviceSets.back()->m_deviceMIMOEngine) // MIMO set else if (m_mainCore->m_deviceSets.back()->m_deviceMIMOEngine) // MIMO set
{ {
DSPDeviceMIMOEngine *lastDeviceEngine = m_mainCore->m_deviceSets.back()->m_deviceMIMOEngine; DSPDeviceMIMOEngine *lastDeviceEngine = m_mainCore->m_deviceSets.back()->m_deviceMIMOEngine;
lastDeviceEngine->stopProcess(1); // Tx side
lastDeviceEngine->stopProcess(0); // Rx side
m_mainCore->m_deviceSets.back()->freeChannels(); m_mainCore->m_deviceSets.back()->freeChannels();
m_mainCore->m_deviceSets.back()->m_deviceAPI->resetSamplingDeviceId(); m_mainCore->m_deviceSets.back()->m_deviceAPI->resetSamplingDeviceId();