diff options
author | David Faure <david.faure@kdab.com> | 2013-08-19 08:45:06 (GMT) |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-11-15 11:42:27 (GMT) |
commit | 521ea9cc0e4014ce5186c727ba30026d7b7edc60 (patch) | |
tree | f717d7f9419009aabe692f29622d0d5530818b4a | |
parent | 735f4851843892a9562dbd59b319d436dc04055b (diff) | |
download | Qt-521ea9cc0e4014ce5186c727ba30026d7b7edc60.zip Qt-521ea9cc0e4014ce5186c727ba30026d7b7edc60.tar.gz Qt-521ea9cc0e4014ce5186c727ba30026d7b7edc60.tar.bz2 |
QThreadPool: fix data races in activeThreadCount()
Rather than trying to make it lock-free (which requires double-bookkeeping of
4 atomic ints!), just lock the mutex before calling it.
tst_bench_qthreadpool shows no difference whatsoever between the two
solutions, I get 0.005 msecs per iteration in startRunnables().
Of course looping over calls to activeThreadCount() is a bit slower,
from 0.0002 msecs per iteration to 0.00027 msecs, i.e. 35% more.
But polling activeThreadCount() from the app is a really wrong thing to
do anyway, this benchmark was just for my own curiosity about the
price of a mutex in a function that sums up 4 ints.
What matters is start() performance, which is unchanged (0.00007 msecs
is just noise compared to a 0.005 total, that's 1.4%).
Backport from qtbase/85b24bb2dea97c3a9b013bacd5a422b26fe5d14b
Change-Id: Id32791069bc1e2dd61cef708d5287c9f9b7e5582
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r-- | src/corelib/concurrent/qthreadpool.cpp | 8 |
1 files changed, 3 insertions, 5 deletions
diff --git a/src/corelib/concurrent/qthreadpool.cpp b/src/corelib/concurrent/qthreadpool.cpp index c3d0292..5435aef 100644 --- a/src/corelib/concurrent/qthreadpool.cpp +++ b/src/corelib/concurrent/qthreadpool.cpp @@ -223,8 +223,6 @@ void QThreadPoolPrivate::enqueueTask(QRunnable *runnable, int priority) int QThreadPoolPrivate::activeThreadCount() const { - // To improve scalability this function is called without holding - // the mutex lock -- keep it thread-safe. return (allThreads.count() - expiredThreads.count() - waitingThreads @@ -500,12 +498,11 @@ bool QThreadPool::tryStart(QRunnable *runnable) Q_D(QThreadPool); - // To improve scalability perform a check on the thread count - // before locking the mutex. + QMutexLocker locker(&d->mutex); + if (d->allThreads.isEmpty() == false && d->activeThreadCount() >= d->maxThreadCount) return false; - QMutexLocker locker(&d->mutex); return d->tryStart(runnable); } @@ -579,6 +576,7 @@ void QThreadPool::setMaxThreadCount(int maxThreadCount) int QThreadPool::activeThreadCount() const { Q_D(const QThreadPool); + QMutexLocker locker(&d->mutex); return d->activeThreadCount(); } |