summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorSvenn-Arne Dragly <svenn-arne.dragly@qt.io>2017-09-05 15:02:20 +0200
committerSvenn-Arne Dragly <svenn-arne.dragly@qt.io>2017-10-04 12:00:33 +0000
commitba423261cd9abedda8b732c82371515003d385ce (patch)
tree78c7a4997deaf6ae6e5b20e99f72c2f03e89f6c3 /tests
parentd7c57fa68e7bfa1fcb1bca3bcc1ea3e3668167a9 (diff)
Improve performance in QThreadPool
When many runnables are executed, this improves the performance by not resizing the queue for each runnable, which was the case in the previous version, because of many calls to QVector::takeFirst(). Also add a test that makes sure tryTake() is safe to call and does not leave the queue in a bad state that tries to use nullptr entries. Change-Id: I608134ecfa9cfc03db4878dcbd6f9c1107e13e90 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp64
1 files changed, 64 insertions, 0 deletions
diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
index fdc4ecb5c8..66853a88d8 100644
--- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
+++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
@@ -93,6 +93,7 @@ private slots:
void waitForDoneTimeout();
void destroyingWaitsForTasksToFinish();
void stressTest();
+ void takeAllAndIncreaseMaxThreadCount();
private:
QMutex m_functionTestMutex;
@@ -1199,5 +1200,68 @@ void tst_QThreadPool::stressTest()
}
}
+void tst_QThreadPool::takeAllAndIncreaseMaxThreadCount() {
+ class Task : public QRunnable
+ {
+ public:
+ Task(QSemaphore *mainBarrier, QSemaphore *threadBarrier)
+ : m_mainBarrier(mainBarrier)
+ , m_threadBarrier(threadBarrier)
+ {
+ setAutoDelete(false);
+ }
+
+ void run() {
+ m_mainBarrier->release();
+ m_threadBarrier->acquire();
+ }
+ private:
+ QSemaphore *m_mainBarrier;
+ QSemaphore *m_threadBarrier;
+ };
+
+ QSemaphore mainBarrier;
+ QSemaphore taskBarrier;
+
+ QThreadPool threadPool;
+ threadPool.setMaxThreadCount(1);
+
+ Task *task1 = new Task(&mainBarrier, &taskBarrier);
+ Task *task2 = new Task(&mainBarrier, &taskBarrier);
+ Task *task3 = new Task(&mainBarrier, &taskBarrier);
+
+ threadPool.start(task1);
+ threadPool.start(task2);
+ threadPool.start(task3);
+
+ mainBarrier.acquire(1);
+
+ QCOMPARE(threadPool.activeThreadCount(), 1);
+
+ QVERIFY(!threadPool.tryTake(task1));
+ QVERIFY(threadPool.tryTake(task2));
+ QVERIFY(threadPool.tryTake(task3));
+
+ // A bad queue implementation can segfault here because two consecutive items in the queue
+ // have been taken
+ threadPool.setMaxThreadCount(4);
+
+ // Even though we increase the max thread count, there should only be one job to run
+ QCOMPARE(threadPool.activeThreadCount(), 1);
+
+ // Make sure jobs 2 and 3 never started
+ QCOMPARE(mainBarrier.available(), 0);
+
+ taskBarrier.release(1);
+
+ threadPool.waitForDone();
+
+ QCOMPARE(threadPool.activeThreadCount(), 0);
+
+ delete task1;
+ delete task2;
+ delete task3;
+}
+
QTEST_MAIN(tst_QThreadPool);
#include "tst_qthreadpool.moc"