mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-11-03 13:11:20 -05:00 
			
		
		
		
	Fixed threading model for DSPDeviceSinkEngine plus other fixes. Part of #2159
This commit is contained in:
		
							parent
							
								
									75d40c8b68
								
							
						
					
					
						commit
						aca4a53513
					
				@ -28,7 +28,7 @@
 | 
			
		||||
#include "dsp/dspcommands.h"
 | 
			
		||||
 | 
			
		||||
DSPDeviceSinkEngine::DSPDeviceSinkEngine(uint32_t uid, QObject* parent) :
 | 
			
		||||
	QThread(parent),
 | 
			
		||||
	QObject(parent),
 | 
			
		||||
    m_uid(uid),
 | 
			
		||||
	m_state(StNotStarted),
 | 
			
		||||
	m_deviceSampleSink(nullptr),
 | 
			
		||||
@ -41,8 +41,6 @@ DSPDeviceSinkEngine::DSPDeviceSinkEngine(uint32_t uid, QObject* parent) :
 | 
			
		||||
{
 | 
			
		||||
    setState(StIdle);
 | 
			
		||||
	connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
 | 
			
		||||
 | 
			
		||||
	moveToThread(this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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()
 | 
			
		||||
{
 | 
			
		||||
	qDebug() << "DSPDeviceSinkEngine::initGeneration";
 | 
			
		||||
@ -101,7 +76,7 @@ bool DSPDeviceSinkEngine::startGeneration()
 | 
			
		||||
void DSPDeviceSinkEngine::stopGeneration()
 | 
			
		||||
{
 | 
			
		||||
	qDebug() << "DSPDeviceSinkEngine::stopGeneration";
 | 
			
		||||
	DSPGenerationStop *cmd = new DSPGenerationStop();
 | 
			
		||||
	auto *cmd = new DSPGenerationStop();
 | 
			
		||||
    getInputMessageQueue()->push(cmd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -122,7 +97,7 @@ void DSPDeviceSinkEngine::setSinkSequence(int sequence)
 | 
			
		||||
void DSPDeviceSinkEngine::addChannelSource(BasebandSampleSource* source)
 | 
			
		||||
{
 | 
			
		||||
	qDebug() << "DSPDeviceSinkEngine::addChannelSource: " << source->getSourceName().toStdString().c_str();
 | 
			
		||||
	DSPAddBasebandSampleSource *cmd = new DSPAddBasebandSampleSource(source);
 | 
			
		||||
	auto *cmd = new DSPAddBasebandSampleSource(source);
 | 
			
		||||
    getInputMessageQueue()->push(cmd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -167,7 +142,10 @@ void DSPDeviceSinkEngine::workSampleFifo()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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();
 | 
			
		||||
 | 
			
		||||
    while ((remainder > 0) && (m_inputMessageQueue.size() == 0))
 | 
			
		||||
@ -208,7 +186,7 @@ void DSPDeviceSinkEngine::workSamples(SampleVector& data, unsigned int iBegin, u
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        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();
 | 
			
		||||
        BasebandSampleSource *source = *srcIt;
 | 
			
		||||
        source->pull(begin, nbSamples);
 | 
			
		||||
@ -328,7 +306,7 @@ DSPDeviceSinkEngine::State DSPDeviceSinkEngine::gotoInit()
 | 
			
		||||
	// pass data to listeners
 | 
			
		||||
	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);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -421,7 +399,7 @@ bool DSPDeviceSinkEngine::handleMessage(const Message& message)
 | 
			
		||||
{
 | 
			
		||||
    if (DSPSignalNotification::match(message))
 | 
			
		||||
    {
 | 
			
		||||
        const DSPSignalNotification& notif = (const DSPSignalNotification&) message;
 | 
			
		||||
        auto& notif = (const DSPSignalNotification&) message;
 | 
			
		||||
 | 
			
		||||
        // update DSP values
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,7 @@
 | 
			
		||||
#ifndef SDRBASE_DSP_DSPDEVICESINKENGINE_H_
 | 
			
		||||
#define SDRBASE_DSP_DSPDEVICESINKENGINE_H_
 | 
			
		||||
 | 
			
		||||
#include <QThread>
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QTimer>
 | 
			
		||||
#include <QMutex>
 | 
			
		||||
#include <QWaitCondition>
 | 
			
		||||
@ -40,7 +40,7 @@ class DeviceSampleSink;
 | 
			
		||||
class BasebandSampleSource;
 | 
			
		||||
class BasebandSampleSink;
 | 
			
		||||
 | 
			
		||||
class SDRBASE_API DSPDeviceSinkEngine : public QThread {
 | 
			
		||||
class SDRBASE_API DSPDeviceSinkEngine : public QObject {
 | 
			
		||||
	Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
@ -52,16 +52,13 @@ public:
 | 
			
		||||
		StError        //!< engine is in error
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	DSPDeviceSinkEngine(uint32_t uid, QObject* parent = NULL);
 | 
			
		||||
	DSPDeviceSinkEngine(uint32_t uid, QObject* parent = nullptr);
 | 
			
		||||
	~DSPDeviceSinkEngine();
 | 
			
		||||
 | 
			
		||||
	uint32_t getUID() const { return m_uid; }
 | 
			
		||||
 | 
			
		||||
	MessageQueue* getInputMessageQueue() { return &m_inputMessageQueue; }
 | 
			
		||||
 | 
			
		||||
	void start(); //!< This thread start
 | 
			
		||||
	void stop();  //!< This thread stop
 | 
			
		||||
 | 
			
		||||
	bool initGeneration(); //!< Initialize generation sequence
 | 
			
		||||
	bool startGeneration(); //!< Start generation sequence
 | 
			
		||||
	void stopGeneration();   //!< Stop generation sequence
 | 
			
		||||
@ -106,7 +103,6 @@ private:
 | 
			
		||||
    bool m_realElseComplex;
 | 
			
		||||
    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 workSamples(SampleVector& data, unsigned int iBegin, unsigned int iEnd);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -111,24 +111,45 @@ void DSPEngine::removeLastDeviceSourceEngine()
 | 
			
		||||
 | 
			
		||||
DSPDeviceSinkEngine *DSPEngine::addDeviceSinkEngine()
 | 
			
		||||
{
 | 
			
		||||
    m_deviceSinkEngines.push_back(new DSPDeviceSinkEngine(m_deviceSinkEnginesUIDSequence));
 | 
			
		||||
    auto *deviceSinkEngine = new DSPDeviceSinkEngine(m_deviceSinkEnginesUIDSequence);
 | 
			
		||||
    auto *deviceThread = new QThread();
 | 
			
		||||
    m_deviceSinkEnginesUIDSequence++;
 | 
			
		||||
    m_deviceEngineReferences.push_back(DeviceEngineReference{1, nullptr, m_deviceSinkEngines.back(), nullptr, nullptr});
 | 
			
		||||
    return m_deviceSinkEngines.back();
 | 
			
		||||
    m_deviceSinkEngines.push_back(deviceSinkEngine);
 | 
			
		||||
    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()
 | 
			
		||||
{
 | 
			
		||||
    if (m_deviceSinkEngines.size() > 0)
 | 
			
		||||
    if (!m_deviceSinkEngines.empty())
 | 
			
		||||
    {
 | 
			
		||||
        DSPDeviceSinkEngine *lastDeviceEngine = m_deviceSinkEngines.back();
 | 
			
		||||
        delete lastDeviceEngine;
 | 
			
		||||
        const DSPDeviceSinkEngine *lastDeviceEngine = m_deviceSinkEngines.back();
 | 
			
		||||
        m_deviceSinkEngines.pop_back();
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < m_deviceEngineReferences.size(); i++)
 | 
			
		||||
        {
 | 
			
		||||
            if (m_deviceEngineReferences[i].m_deviceSinkEngine == lastDeviceEngine)
 | 
			
		||||
            {
 | 
			
		||||
                QThread* deviceThread = m_deviceEngineReferences[i].m_thread;
 | 
			
		||||
                deviceThread->exit();
 | 
			
		||||
                deviceThread->wait();
 | 
			
		||||
                m_deviceEngineReferences.removeAt(i);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
@ -201,7 +222,9 @@ void DSPEngine::removeDeviceEngineAt(int deviceIndex)
 | 
			
		||||
    else if (m_deviceEngineReferences[deviceIndex].m_deviceEngineType == 1) // sink
 | 
			
		||||
    {
 | 
			
		||||
        DSPDeviceSinkEngine *deviceEngine = m_deviceEngineReferences[deviceIndex].m_deviceSinkEngine;
 | 
			
		||||
        delete deviceEngine;
 | 
			
		||||
        QThread *deviceThread = m_deviceEngineReferences[deviceIndex].m_thread;
 | 
			
		||||
        deviceThread->exit();
 | 
			
		||||
        deviceThread->wait();
 | 
			
		||||
        m_deviceSinkEngines.removeAll(deviceEngine);
 | 
			
		||||
    }
 | 
			
		||||
    else if (m_deviceEngineReferences[deviceIndex].m_deviceEngineType == 2) // MIMO
 | 
			
		||||
 | 
			
		||||
@ -565,7 +565,6 @@ void MainWindow::sampleSourceCreate(
 | 
			
		||||
void MainWindow::sampleSinkAdd(Workspace *deviceWorkspace, Workspace *spectrumWorkspace, int deviceIndex)
 | 
			
		||||
{
 | 
			
		||||
    DSPDeviceSinkEngine *dspDeviceSinkEngine = m_dspEngine->addDeviceSinkEngine();
 | 
			
		||||
    dspDeviceSinkEngine->start();
 | 
			
		||||
 | 
			
		||||
    uint dspDeviceSinkEngineUID =  dspDeviceSinkEngine->getUID();
 | 
			
		||||
    char uidCStr[16];
 | 
			
		||||
@ -993,7 +992,6 @@ void MainWindow::removeDeviceSet(int deviceSetIndex)
 | 
			
		||||
    if (deviceUISet->m_deviceSourceEngine) // source device
 | 
			
		||||
    {
 | 
			
		||||
        DSPDeviceSourceEngine *deviceEngine = deviceUISet->m_deviceSourceEngine;
 | 
			
		||||
        deviceEngine->stopAcquistion();
 | 
			
		||||
        deviceEngine->removeSink(deviceUISet->m_spectrumVis);
 | 
			
		||||
 | 
			
		||||
        // deletes old UI and core object
 | 
			
		||||
@ -1015,7 +1013,6 @@ void MainWindow::removeDeviceSet(int deviceSetIndex)
 | 
			
		||||
    else if (deviceUISet->m_deviceSinkEngine) // sink device
 | 
			
		||||
    {
 | 
			
		||||
	    DSPDeviceSinkEngine *deviceEngine = deviceUISet->m_deviceSinkEngine;
 | 
			
		||||
        deviceEngine->stopGeneration();
 | 
			
		||||
        deviceEngine->removeSpectrumSink(deviceUISet->m_spectrumVis);
 | 
			
		||||
 | 
			
		||||
        // 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_deviceGUI->destroy();
 | 
			
		||||
        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;
 | 
			
		||||
 | 
			
		||||
        deviceEngine->stop();
 | 
			
		||||
        m_dspEngine->removeDeviceEngineAt(deviceSetIndex);
 | 
			
		||||
        DeviceEnumerator::instance()->removeTxSelection(deviceSetIndex);
 | 
			
		||||
 | 
			
		||||
	    DeviceAPI *sinkAPI = deviceUISet->m_deviceAPI;
 | 
			
		||||
        delete deviceUISet;
 | 
			
		||||
        delete sinkAPI->getSampleSink();
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
        // deletes old UI and output object
 | 
			
		||||
@ -1096,7 +1088,6 @@ void MainWindow::removeLastDeviceSet()
 | 
			
		||||
    if (m_deviceUIs.back()->m_deviceSourceEngine) // source tab
 | 
			
		||||
	{
 | 
			
		||||
	    DSPDeviceSourceEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceSourceEngine;
 | 
			
		||||
        lastDeviceEngine->stopAcquistion();
 | 
			
		||||
        lastDeviceEngine->removeSink(m_deviceUIs.back()->m_spectrumVis);
 | 
			
		||||
 | 
			
		||||
        // deletes old UI and input object
 | 
			
		||||
@ -1116,7 +1107,6 @@ void MainWindow::removeLastDeviceSet()
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
        // deletes old UI and output object
 | 
			
		||||
@ -1136,8 +1126,6 @@ void MainWindow::removeLastDeviceSet()
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
        // deletes old UI and output object
 | 
			
		||||
 | 
			
		||||
@ -270,7 +270,6 @@ void MainServer::applySettings()
 | 
			
		||||
void MainServer::addSinkDevice()
 | 
			
		||||
{
 | 
			
		||||
    DSPDeviceSinkEngine *dspDeviceSinkEngine = m_dspEngine->addDeviceSinkEngine();
 | 
			
		||||
    dspDeviceSinkEngine->start();
 | 
			
		||||
 | 
			
		||||
    uint dspDeviceSinkEngineUID =  dspDeviceSinkEngine->getUID();
 | 
			
		||||
    char uidCStr[16];
 | 
			
		||||
@ -398,7 +397,6 @@ void MainServer::removeLastDevice()
 | 
			
		||||
    if (m_mainCore->m_deviceSets.back()->m_deviceSourceEngine) // source set
 | 
			
		||||
    {
 | 
			
		||||
        DSPDeviceSourceEngine *lastDeviceEngine = m_mainCore->m_deviceSets.back()->m_deviceSourceEngine;
 | 
			
		||||
        lastDeviceEngine->stopAcquistion();
 | 
			
		||||
 | 
			
		||||
        // deletes old UI and input object
 | 
			
		||||
        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
 | 
			
		||||
    {
 | 
			
		||||
        DSPDeviceSinkEngine *lastDeviceEngine = m_mainCore->m_deviceSets.back()->m_deviceSinkEngine;
 | 
			
		||||
        lastDeviceEngine->stopGeneration();
 | 
			
		||||
 | 
			
		||||
        // deletes old UI and output object
 | 
			
		||||
        m_mainCore->m_deviceSets.back()->freeChannels();
 | 
			
		||||
        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_dspEngine->removeLastDeviceSinkEngine();
 | 
			
		||||
 | 
			
		||||
        DeviceAPI *sinkAPI = m_mainCore->m_deviceSets.back()->m_deviceAPI;
 | 
			
		||||
        delete m_mainCore->m_deviceSets.back();
 | 
			
		||||
 | 
			
		||||
        lastDeviceEngine->stop();
 | 
			
		||||
        m_dspEngine->removeLastDeviceSinkEngine();
 | 
			
		||||
 | 
			
		||||
        delete sinkAPI->getSampleSink();
 | 
			
		||||
        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();
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user