From 2ea7c6c4fd86eae8e7aa95576824938d913242ca Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 29 Apr 2018 17:01:51 +0200 Subject: [PATCH 1/2] Fix job queue crash * Don't add jobs when job queue is full * Icrease job queue size from 1024 to 8192 --- include/MixerWorkerThread.h | 2 +- src/core/MixerWorkerThread.cpp | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/MixerWorkerThread.h b/include/MixerWorkerThread.h index 8b900195f4f..4af42897cb2 100644 --- a/include/MixerWorkerThread.h +++ b/include/MixerWorkerThread.h @@ -62,7 +62,7 @@ class MixerWorkerThread : public QThread void wait(); private: -#define JOB_QUEUE_SIZE 1024 +#define JOB_QUEUE_SIZE 8192 QAtomicPointer m_items[JOB_QUEUE_SIZE]; AtomicInt m_queueSize; AtomicInt m_itemsDone; diff --git a/src/core/MixerWorkerThread.cpp b/src/core/MixerWorkerThread.cpp index e8c6bd61c08..14363f4d125 100644 --- a/src/core/MixerWorkerThread.cpp +++ b/src/core/MixerWorkerThread.cpp @@ -25,6 +25,7 @@ #include "MixerWorkerThread.h" #include "denormals.h" +#include #include #include #include "ThreadableJob.h" @@ -54,7 +55,13 @@ void MixerWorkerThread::JobQueue::addJob( ThreadableJob * _job ) // update job state _job->queue(); // actually queue the job via atomic operations - m_items[m_queueSize.fetchAndAddOrdered(1)] = _job; + auto index = m_queueSize.fetchAndAddOrdered(1); + if (index < JOB_QUEUE_SIZE) { + m_items[index] = _job; + } else { + qWarning() << "Job queue is full!"; + m_itemsDone.fetchAndAddOrdered(1); + } } } @@ -66,7 +73,7 @@ void MixerWorkerThread::JobQueue::run() while( processedJob && (int) m_itemsDone < (int) m_queueSize ) { processedJob = false; - for( int i = 0; i < m_queueSize; ++i ) + for( int i = 0; i < m_queueSize && i < JOB_QUEUE_SIZE; ++i ) { ThreadableJob * job = m_items[i].fetchAndStoreOrdered( NULL ); if( job ) From bd608ed353a2a00da06b40052e3432ef4176fff2 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Wed, 2 May 2018 12:54:45 +0200 Subject: [PATCH 2/2] JobQueue: Rename m_queueSize to m_writeIndex Hopefully makes it less confusing that m_writeIndex grows beyond JOB_QUEUE_SIZE when the queue is full. --- include/MixerWorkerThread.h | 4 ++-- src/core/MixerWorkerThread.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/MixerWorkerThread.h b/include/MixerWorkerThread.h index 4af42897cb2..8d6b0c72a26 100644 --- a/include/MixerWorkerThread.h +++ b/include/MixerWorkerThread.h @@ -48,7 +48,7 @@ class MixerWorkerThread : public QThread JobQueue() : m_items(), - m_queueSize( 0 ), + m_writeIndex( 0 ), m_itemsDone( 0 ), m_opMode( Static ) { @@ -64,7 +64,7 @@ class MixerWorkerThread : public QThread private: #define JOB_QUEUE_SIZE 8192 QAtomicPointer m_items[JOB_QUEUE_SIZE]; - AtomicInt m_queueSize; + AtomicInt m_writeIndex; AtomicInt m_itemsDone; OperationMode m_opMode; diff --git a/src/core/MixerWorkerThread.cpp b/src/core/MixerWorkerThread.cpp index 14363f4d125..ae5d505647b 100644 --- a/src/core/MixerWorkerThread.cpp +++ b/src/core/MixerWorkerThread.cpp @@ -40,7 +40,7 @@ QList MixerWorkerThread::workerThreads; // implementation of internal JobQueue void MixerWorkerThread::JobQueue::reset( OperationMode _opMode ) { - m_queueSize = 0; + m_writeIndex = 0; m_itemsDone = 0; m_opMode = _opMode; } @@ -55,7 +55,7 @@ void MixerWorkerThread::JobQueue::addJob( ThreadableJob * _job ) // update job state _job->queue(); // actually queue the job via atomic operations - auto index = m_queueSize.fetchAndAddOrdered(1); + auto index = m_writeIndex.fetchAndAddOrdered(1); if (index < JOB_QUEUE_SIZE) { m_items[index] = _job; } else { @@ -70,10 +70,10 @@ void MixerWorkerThread::JobQueue::addJob( ThreadableJob * _job ) void MixerWorkerThread::JobQueue::run() { bool processedJob = true; - while( processedJob && (int) m_itemsDone < (int) m_queueSize ) + while( processedJob && (int) m_itemsDone < (int) m_writeIndex ) { processedJob = false; - for( int i = 0; i < m_queueSize && i < JOB_QUEUE_SIZE; ++i ) + for( int i = 0; i < m_writeIndex && i < JOB_QUEUE_SIZE; ++i ) { ThreadableJob * job = m_items[i].fetchAndStoreOrdered( NULL ); if( job ) @@ -93,7 +93,7 @@ void MixerWorkerThread::JobQueue::run() void MixerWorkerThread::JobQueue::wait() { - while( (int) m_itemsDone < (int) m_queueSize ) + while( (int) m_itemsDone < (int) m_writeIndex ) { #if defined(LMMS_HOST_X86) || defined(LMMS_HOST_X86_64) asm( "pause" );