1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-25 01:18:38 -05:00

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

This commit is contained in:
f4exb 2024-08-17 11:24:19 +02:00
parent f5e7708612
commit 436d1665ea
7 changed files with 109 additions and 116 deletions

View File

@ -66,6 +66,7 @@ MetisMISO::MetisMISO(DeviceAPI *deviceAPI) :
MetisMISO::~MetisMISO()
{
qDebug("MetisMISO::~MetisMISO");
QObject::disconnect(
m_networkManager,
&QNetworkAccessManager::finished,
@ -77,6 +78,7 @@ MetisMISO::~MetisMISO()
if (m_running) {
stopRx();
}
qDebug("MetisMISO::~MetisMISO: end");
}
void MetisMISO::destroy()
@ -155,6 +157,7 @@ void MetisMISO::startMetis()
void MetisMISO::stopMetis()
{
qDebug("MetisMISO::stopMetis");
MetisMISOUDPHandler::MsgStartStop *message = MetisMISOUDPHandler::MsgStartStop::create(false);
m_udpHandler.getInputMessageQueue()->push(message);
}

View File

@ -41,7 +41,7 @@ MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::ConfigureCorrection, Message)
MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::SetSpectrumSinkInput, Message)
DSPDeviceMIMOEngine::DSPDeviceMIMOEngine(uint32_t uid, QObject* parent) :
QThread(parent),
QObject(parent),
m_uid(uid),
m_stateRx(StNotStarted),
m_stateTx(StNotStarted),
@ -49,15 +49,14 @@ DSPDeviceMIMOEngine::DSPDeviceMIMOEngine(uint32_t uid, QObject* parent) :
m_spectrumInputSourceElseSink(true),
m_spectrumInputIndex(0)
{
setStateRx(StIdle);
setStateTx(StIdle);
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
moveToThread(this);
}
DSPDeviceMIMOEngine::~DSPDeviceMIMOEngine()
{
stop();
wait();
qDebug("DSPDeviceMIMOEngine::~DSPDeviceMIMOEngine");
}
void DSPDeviceMIMOEngine::setStateRx(State state)
@ -78,30 +77,6 @@ void DSPDeviceMIMOEngine::setStateTx(State state)
}
}
void DSPDeviceMIMOEngine::run()
{
qDebug() << "DSPDeviceMIMOEngine::run";
setStateRx(StIdle);
setStateTx(StIdle);
exec();
}
void DSPDeviceMIMOEngine::start()
{
qDebug() << "DSPDeviceMIMOEngine::start";
QThread::start();
}
void DSPDeviceMIMOEngine::stop()
{
qDebug() << "DSPDeviceMIMOEngine::stop";
gotoIdle(0); // Rx
gotoIdle(1); // Tx
setStateRx(StNotStarted);
setStateTx(StNotStarted);
QThread::exit();
}
bool DSPDeviceMIMOEngine::initProcess(int subsystemIndex)
{
qDebug() << "DSPDeviceMIMOEngine::initProcess: subsystemIndex: " << subsystemIndex;

View File

@ -19,7 +19,7 @@
#ifndef SDRBASE_DSP_DSPDEVICEMIMOENGINE_H_
#define SDRBASE_DSP_DSPDEVICEMIMOENGINE_H_
#include <QThread>
#include <QObject>
#include "dsp/dsptypes.h"
#include "util/message.h"
@ -33,7 +33,7 @@ class BasebandSampleSink;
class BasebandSampleSource;
class MIMOChannel;
class SDRBASE_API DSPDeviceMIMOEngine : public QThread {
class SDRBASE_API DSPDeviceMIMOEngine : public QObject {
Q_OBJECT
public:
@ -213,13 +213,10 @@ public:
};
DSPDeviceMIMOEngine(uint32_t uid, QObject* parent = nullptr);
~DSPDeviceMIMOEngine();
~DSPDeviceMIMOEngine() override;
MessageQueue* getInputMessageQueue() { return &m_inputMessageQueue; }
void start(); //!< This thread start
void stop(); //!< This thread stop
bool initProcess(int subsystemIndex); //!< Initialize process sequence
bool startProcess(int subsystemIndex); //!< Start process sequence
void stopProcess(int subsystemIndex); //!< Stop process sequence
@ -339,7 +336,6 @@ private:
bool m_spectrumInputSourceElseSink; //!< Source else sink stream to be used as spectrum sink input
unsigned int m_spectrumInputIndex; //!< Index of the stream to be used as spectrum sink input
void run();
void workSampleSinkFifos(); //!< transfer samples of all sink streams (sync mode)
void workSampleSinkFifo(unsigned int streamIndex); //!< transfer samples of one sink stream (async mode)
void workSamplesSink(const SampleVector::const_iterator& vbegin, const SampleVector::const_iterator& vend, unsigned int streamIndex);

View File

@ -52,6 +52,7 @@ DSPDeviceSourceEngine::DSPDeviceSourceEngine(uint uid, QObject* parent) :
DSPDeviceSourceEngine::~DSPDeviceSourceEngine()
{
qDebug("DSPDeviceSourceEngine::~DSPDeviceSourceEngine");
}
void DSPDeviceSourceEngine::setState(State state)

View File

@ -138,24 +138,45 @@ void DSPEngine::removeLastDeviceSinkEngine()
DSPDeviceMIMOEngine *DSPEngine::addDeviceMIMOEngine()
{
m_deviceMIMOEngines.push_back(new DSPDeviceMIMOEngine(m_deviceMIMOEnginesUIDSequence));
auto *deviceMIMOEngine = new DSPDeviceMIMOEngine(m_deviceMIMOEnginesUIDSequence);
auto *deviceThread = new QThread();
m_deviceMIMOEnginesUIDSequence++;
m_deviceEngineReferences.push_back(DeviceEngineReference{2, nullptr, nullptr, m_deviceMIMOEngines.back(), nullptr});
return m_deviceMIMOEngines.back();
m_deviceMIMOEngines.push_back(deviceMIMOEngine);
m_deviceEngineReferences.push_back(DeviceEngineReference{2, nullptr, nullptr, m_deviceMIMOEngines.back(), deviceThread});
deviceMIMOEngine->moveToThread(deviceThread);
QObject::connect(
deviceThread,
&QThread::finished,
deviceMIMOEngine,
&QObject::deleteLater
);
QObject::connect(
deviceThread,
&QThread::finished,
deviceThread,
&QThread::deleteLater
);
deviceThread->start();
return deviceMIMOEngine;
}
void DSPEngine::removeLastDeviceMIMOEngine()
{
if (m_deviceMIMOEngines.size() > 0)
if (!m_deviceMIMOEngines.empty())
{
DSPDeviceMIMOEngine *lastDeviceEngine = m_deviceMIMOEngines.back();
delete lastDeviceEngine;
const DSPDeviceMIMOEngine *lastDeviceEngine = m_deviceMIMOEngines.back();
m_deviceMIMOEngines.pop_back();
for (int i = 0; i < m_deviceEngineReferences.size(); i++)
{
if (m_deviceEngineReferences[i].m_deviceMIMOEngine == lastDeviceEngine)
{
QThread* deviceThread = m_deviceEngineReferences[i].m_thread;
deviceThread->exit();
deviceThread->wait();
m_deviceEngineReferences.removeAt(i);
break;
}
@ -186,7 +207,9 @@ void DSPEngine::removeDeviceEngineAt(int deviceIndex)
else if (m_deviceEngineReferences[deviceIndex].m_deviceEngineType == 2) // MIMO
{
DSPDeviceMIMOEngine *deviceEngine = m_deviceEngineReferences[deviceIndex].m_deviceMIMOEngine;
delete deviceEngine;
QThread *deviceThread = m_deviceEngineReferences[deviceIndex].m_thread;
deviceThread->exit();
deviceThread->wait();
m_deviceMIMOEngines.removeAll(deviceEngine);
}

View File

@ -783,7 +783,6 @@ void MainWindow::sampleSinkCreate(
void MainWindow::sampleMIMOAdd(Workspace *deviceWorkspace, Workspace *spectrumWorkspace, int deviceIndex)
{
DSPDeviceMIMOEngine *dspDeviceMIMOEngine = m_dspEngine->addDeviceMIMOEngine();
dspDeviceMIMOEngine->start();
uint dspDeviceMIMOEngineUID = dspDeviceMIMOEngine->getUID();
char uidCStr[16];
@ -1002,65 +1001,62 @@ void MainWindow::removeDeviceSet(int deviceSetIndex)
deviceUISet->m_deviceAPI->getSampleSource()->setMessageQueueToGUI(nullptr); // have source stop sending messages to the GUI
deviceUISet->m_deviceGUI->destroy();
deviceUISet->m_deviceAPI->resetSamplingDeviceId();
deviceUISet->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceInput(
deviceUISet->m_deviceAPI->getSampleSource());
deviceUISet->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists
DeviceAPI *sourceAPI = deviceUISet->m_deviceAPI;
delete deviceUISet;
m_dspEngine->removeDeviceEngineAt(deviceSetIndex);
m_dspEngine->removeDeviceEngineAt(deviceSetIndex);
DeviceEnumerator::instance()->removeRxSelection(deviceSetIndex);
delete sourceAPI;
DeviceAPI *sourceAPI = deviceUISet->m_deviceAPI;
delete deviceUISet;
delete sourceAPI->getSampleSource();
delete sourceAPI;
}
else if (deviceUISet->m_deviceSinkEngine) // sink device
{
DSPDeviceSinkEngine *deviceEngine = deviceUISet->m_deviceSinkEngine;
deviceEngine->stopGeneration();
deviceEngine->removeSpectrumSink(deviceUISet->m_spectrumVis);
deviceEngine->stopGeneration();
deviceEngine->removeSpectrumSink(deviceUISet->m_spectrumVis);
// deletes old UI and output object
deviceUISet->freeChannels();
deviceUISet->m_deviceAPI->getSampleSink()->setMessageQueueToGUI(nullptr); // have sink stop sending messages to the GUI
deviceUISet->m_deviceGUI->destroy();
deviceUISet->m_deviceAPI->resetSamplingDeviceId();
deviceUISet->m_deviceAPI->getPluginInterface()->deleteSampleSinkPluginInstanceOutput(
deviceUISet->m_deviceAPI->getSampleSink());
deviceUISet->m_deviceAPI->resetSamplingDeviceId();
deviceUISet->m_deviceAPI->getPluginInterface()->deleteSampleSinkPluginInstanceOutput(
deviceUISet->m_deviceAPI->getSampleSink());
deviceUISet->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists
DeviceAPI *sinkAPI = deviceUISet->m_deviceAPI;
delete deviceUISet;
delete deviceUISet;
deviceEngine->stop();
m_dspEngine->removeDeviceEngineAt(deviceSetIndex);
deviceEngine->stop();
m_dspEngine->removeDeviceEngineAt(deviceSetIndex);
DeviceEnumerator::instance()->removeTxSelection(deviceSetIndex);
delete sinkAPI;
delete sinkAPI;
}
else if (deviceUISet->m_deviceMIMOEngine) // MIMO device
{
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
deviceUISet->freeChannels();
deviceUISet->m_deviceAPI->getSampleMIMO()->setMessageQueueToGUI(nullptr); // have sink stop sending messages to the GUI
deviceUISet->m_deviceGUI->destroy();
deviceUISet->m_deviceAPI->resetSamplingDeviceId();
deviceUISet->m_deviceAPI->getPluginInterface()->deleteSampleMIMOPluginInstanceMIMO(
deviceUISet->m_deviceAPI->getSampleMIMO());
deviceUISet->m_deviceAPI->resetSamplingDeviceId();
DeviceAPI *mimoAPI = deviceUISet->m_deviceAPI;
delete deviceUISet;
deviceEngine->stop();
m_dspEngine->removeDeviceEngineAt(deviceSetIndex);
m_dspEngine->removeDeviceEngineAt(deviceSetIndex);
DeviceEnumerator::instance()->removeMIMOSelection(deviceSetIndex);
delete mimoAPI;
DeviceAPI *mimoAPI = deviceUISet->m_deviceAPI;
delete deviceUISet;
delete mimoAPI->getSampleMIMO();
delete mimoAPI;
}
m_deviceUIs.erase(m_deviceUIs.begin() + deviceSetIndex);
@ -1094,75 +1090,72 @@ void MainWindow::removeDeviceSet(int deviceSetIndex)
void MainWindow::removeLastDeviceSet()
{
qDebug("MainWindow::removeLastDeviceSet: %s", qPrintable(m_deviceUIs.back()->m_deviceAPI->getHardwareId()));
int removedDeviceSetIndex = m_deviceUIs.size() - 1;
if (m_deviceUIs.back()->m_deviceSourceEngine) // source tab
{
DSPDeviceSourceEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceSourceEngine;
lastDeviceEngine->stopAcquistion();
lastDeviceEngine->removeSink(m_deviceUIs.back()->m_spectrumVis);
lastDeviceEngine->stopAcquistion();
lastDeviceEngine->removeSink(m_deviceUIs.back()->m_spectrumVis);
// deletes old UI and input object
m_deviceUIs.back()->freeChannels(); // destroys the channel instances
m_deviceUIs.back()->m_deviceAPI->getSampleSource()->setMessageQueueToGUI(nullptr); // have source stop sending messages to the GUI
m_deviceUIs.back()->m_deviceGUI->destroy();
m_deviceUIs.back()->m_deviceAPI->resetSamplingDeviceId();
m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceInput(
m_deviceUIs.back()->m_deviceAPI->getSampleSource());
m_deviceUIs.back()->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists
m_dspEngine->removeLastDeviceSourceEngine();
DeviceAPI *sourceAPI = m_deviceUIs.back()->m_deviceAPI;
delete m_deviceUIs.back();
m_dspEngine->removeLastDeviceSourceEngine();
delete sourceAPI;
delete m_deviceUIs.back();
delete sourceAPI->getSampleSource();
delete sourceAPI;
}
else if (m_deviceUIs.back()->m_deviceSinkEngine) // sink tab
{
DSPDeviceSinkEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceSinkEngine;
lastDeviceEngine->stopGeneration();
lastDeviceEngine->removeSpectrumSink(m_deviceUIs.back()->m_spectrumVis);
lastDeviceEngine->stopGeneration();
lastDeviceEngine->removeSpectrumSink(m_deviceUIs.back()->m_spectrumVis);
// deletes old UI and output object
m_deviceUIs.back()->freeChannels();
m_deviceUIs.back()->m_deviceAPI->getSampleSink()->setMessageQueueToGUI(nullptr); // have sink stop sending messages to the GUI
m_deviceUIs.back()->m_deviceGUI->destroy();
m_deviceUIs.back()->m_deviceAPI->resetSamplingDeviceId();
m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleSinkPluginInstanceOutput(
m_deviceUIs.back()->m_deviceAPI->getSampleSink());
m_deviceUIs.back()->m_deviceAPI->resetSamplingDeviceId();
m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleSinkPluginInstanceOutput(
m_deviceUIs.back()->m_deviceAPI->getSampleSink());
m_deviceUIs.back()->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists
DeviceAPI *sinkAPI = m_deviceUIs.back()->m_deviceAPI;
delete m_deviceUIs.back();
delete m_deviceUIs.back();
lastDeviceEngine->stop();
m_dspEngine->removeLastDeviceSinkEngine();
lastDeviceEngine->stop();
m_dspEngine->removeLastDeviceSinkEngine();
delete sinkAPI;
delete sinkAPI;
}
else if (m_deviceUIs.back()->m_deviceMIMOEngine) // MIMO tab
{
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
m_deviceUIs.back()->freeChannels();
m_deviceUIs.back()->m_deviceAPI->getSampleMIMO()->setMessageQueueToGUI(nullptr); // have sink stop sending messages to the GUI
m_deviceUIs.back()->m_deviceGUI->destroy();
m_deviceUIs.back()->m_deviceAPI->resetSamplingDeviceId();
m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleMIMOPluginInstanceMIMO(
m_deviceUIs.back()->m_deviceAPI->getSampleMIMO());
m_deviceUIs.back()->m_deviceAPI->resetSamplingDeviceId();
m_dspEngine->removeLastDeviceMIMOEngine();
DeviceAPI *mimoAPI = m_deviceUIs.back()->m_deviceAPI;
delete m_deviceUIs.back();
lastDeviceEngine->stop();
m_dspEngine->removeLastDeviceMIMOEngine();
delete mimoAPI;
delete m_deviceUIs.back();
delete mimoAPI->getSampleMIMO();
delete mimoAPI;
}
m_deviceUIs.pop_back();

View File

@ -27,6 +27,9 @@
#include "dsp/dspdevicesourceengine.h"
#include "dsp/dspdevicesinkengine.h"
#include "dsp/dspdevicemimoengine.h"
#include "dsp/devicesamplesource.h"
#include "dsp/devicesamplesink.h"
#include "dsp/devicesamplemimo.h"
#include "dsp/spectrumvis.h"
#include "device/deviceapi.h"
#include "device/deviceset.h"
@ -316,10 +319,6 @@ void MainServer::addSourceDevice()
{
DSPDeviceSourceEngine *dspDeviceSourceEngine = m_dspEngine->addDeviceSourceEngine();
uint dspDeviceSourceEngineUID = dspDeviceSourceEngine->getUID();
char uidCStr[16];
sprintf(uidCStr, "UID:%d", dspDeviceSourceEngineUID);
int deviceTabIndex = m_mainCore->m_deviceSets.size();
m_mainCore->m_deviceSets.push_back(new DeviceSet(deviceTabIndex, 0));
m_mainCore->m_deviceSets.back()->m_deviceSourceEngine = dspDeviceSourceEngine;
@ -327,9 +326,6 @@ void MainServer::addSourceDevice()
m_mainCore->m_deviceSets.back()->m_deviceMIMOEngine = nullptr;
dspDeviceSourceEngine->addSink(m_mainCore->m_deviceSets.back()->m_spectrumVis);
char tabNameCStr[16];
sprintf(tabNameCStr, "R%d", deviceTabIndex);
DeviceAPI *deviceAPI = new DeviceAPI(DeviceAPI::StreamSingleRx, deviceTabIndex, dspDeviceSourceEngine, nullptr, nullptr);
m_mainCore->m_deviceSets.back()->m_deviceAPI = deviceAPI;
@ -361,11 +357,6 @@ void MainServer::addSourceDevice()
void MainServer::addMIMODevice()
{
DSPDeviceMIMOEngine *dspDeviceMIMOEngine = m_dspEngine->addDeviceMIMOEngine();
dspDeviceMIMOEngine->start();
uint dspDeviceMIMOEngineUID = dspDeviceMIMOEngine->getUID();
char uidCStr[16];
sprintf(uidCStr, "UID:%d", dspDeviceMIMOEngineUID);
int deviceTabIndex = m_mainCore->m_deviceSets.size();
m_mainCore->m_deviceSets.push_back(new DeviceSet(deviceTabIndex, 2));
@ -374,9 +365,6 @@ void MainServer::addMIMODevice()
m_mainCore->m_deviceSets.back()->m_deviceMIMOEngine = dspDeviceMIMOEngine;
dspDeviceMIMOEngine->addSpectrumSink(m_mainCore->m_deviceSets.back()->m_spectrumVis);
char tabNameCStr[16];
sprintf(tabNameCStr, "M%d", deviceTabIndex);
DeviceAPI *deviceAPI = new DeviceAPI(DeviceAPI::StreamMIMO, deviceTabIndex, nullptr, nullptr, dspDeviceMIMOEngine);
// create a test MIMO by default
@ -415,15 +403,13 @@ void MainServer::removeLastDevice()
// deletes old UI and input object
m_mainCore->m_deviceSets.back()->freeChannels(); // destroys the channel instances
m_mainCore->m_deviceSets.back()->m_deviceAPI->resetSamplingDeviceId();
m_mainCore->m_deviceSets.back()->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceInput(
m_mainCore->m_deviceSets.back()->m_deviceAPI->getSampleSource());
m_mainCore->m_deviceSets.back()->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists
DeviceAPI *sourceAPI = m_mainCore->m_deviceSets.back()->m_deviceAPI;
delete m_mainCore->m_deviceSets.back();
m_dspEngine->removeLastDeviceSourceEngine();
DeviceAPI *sourceAPI = m_mainCore->m_deviceSets.back()->m_deviceAPI;
delete m_mainCore->m_deviceSets.back();
delete sourceAPI->getSampleSource();
delete sourceAPI;
}
else if (m_mainCore->m_deviceSets.back()->m_deviceSinkEngine) // sink set
@ -446,6 +432,22 @@ void MainServer::removeLastDevice()
delete sinkAPI;
}
else if (m_mainCore->m_deviceSets.back()->m_deviceMIMOEngine) // MIMO set
{
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()->m_deviceAPI->resetSamplingDeviceId();
m_dspEngine->removeLastDeviceSourceEngine();
DeviceAPI *mimoAPI = m_mainCore->m_deviceSets.back()->m_deviceAPI;
delete m_mainCore->m_deviceSets.back();
delete mimoAPI->getSampleMIMO();
delete mimoAPI;
}
m_mainCore->m_deviceSets.pop_back();
emit m_mainCore->deviceSetRemoved(removedTabIndex);