From 343e5d066a6b5583688e16baec20f20e6d9a24e0 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 6 Nov 2015 09:37:23 +0100 Subject: Optimized implementation of QReadWriteLock QReadWriteLock is supposed to be a better alternative to QMutex when there are only a few writers but potentially lots of reads. However, in practice the previous implementation was much slower, unless you really do a lot of work with the lock for read and you have lots of contention. Indeed, the previous implementation was locking a QMutex both for lock, and unlock (making it already at least twice as slow as QMutex). This new implementation brings QReadWriteLock back to the same level as QMutex: - No memory allocations in the uncontended case (almost no overhead allowing to create many of them in classes) - Lock-free if there is no contention Should support up to 2^31 concurrent readers on 64 bit platforms, and 2^28 on 32 bit platforms Change-Id: Ifa2fc999075cbb971088f4ee8e6fde78ce262da3 Reviewed-by: Edward Welbourne Reviewed-by: Sean Harmer Reviewed-by: Robin Burchell --- src/corelib/thread/qwaitcondition_win.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/corelib/thread/qwaitcondition_win.cpp') diff --git a/src/corelib/thread/qwaitcondition_win.cpp b/src/corelib/thread/qwaitcondition_win.cpp index 246e45a54c..f3a645c504 100644 --- a/src/corelib/thread/qwaitcondition_win.cpp +++ b/src/corelib/thread/qwaitcondition_win.cpp @@ -191,20 +191,22 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time) bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time) { - if (!readWriteLock || readWriteLock->d->accessCount == 0) + if (!readWriteLock) return false; - if (readWriteLock->d->accessCount < -1) { + auto previousState = readWriteLock->stateForWaitCondition(); + if (previousState == QReadWriteLock::Unlocked) + return false; + if (previousState == QReadWriteLock::RecursivelyLocked) { qWarning("QWaitCondition: cannot wait on QReadWriteLocks with recursive lockForWrite()"); return false; } QWaitConditionEvent *wce = d->pre(); - int previousAccessCount = readWriteLock->d->accessCount; readWriteLock->unlock(); bool returnValue = d->wait(wce, time); - if (previousAccessCount < 0) + if (previousState == QReadWriteLock::LockedForWrite) readWriteLock->lockForWrite(); else readWriteLock->lockForRead(); -- cgit v1.2.3