summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qreadwritelock_p.h
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@woboq.com>2015-11-06 09:37:23 +0100
committerOlivier Goffart (Woboq GmbH) <ogoffart@woboq.com>2016-03-11 13:32:13 +0000
commit343e5d066a6b5583688e16baec20f20e6d9a24e0 (patch)
tree41e1d382cd9e87ef2bfbe39e6e8bafcff1bbb0e1 /src/corelib/thread/qreadwritelock_p.h
parent71548ba4a02e7d80a5ea407ff910b70ca21f9b5b (diff)
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 <edward.welbourne@theqtcompany.com> Reviewed-by: Sean Harmer <sean.harmer@kdab.com> Reviewed-by: Robin Burchell <robin.burchell@viroteck.net>
Diffstat (limited to 'src/corelib/thread/qreadwritelock_p.h')
-rw-r--r--src/corelib/thread/qreadwritelock_p.h39
1 files changed, 29 insertions, 10 deletions
diff --git a/src/corelib/thread/qreadwritelock_p.h b/src/corelib/thread/qreadwritelock_p.h
index 1f6f73c8e3..285f017655 100644
--- a/src/corelib/thread/qreadwritelock_p.h
+++ b/src/corelib/thread/qreadwritelock_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -53,29 +54,47 @@
#include <QtCore/qglobal.h>
#include <QtCore/qhash.h>
+#include <QtCore/QWaitCondition>
#ifndef QT_NO_THREAD
QT_BEGIN_NAMESPACE
-struct QReadWriteLockPrivate
+class QReadWriteLockPrivate
{
- QReadWriteLockPrivate(QReadWriteLock::RecursionMode recursionMode)
- : accessCount(0), waitingReaders(0), waitingWriters(0),
- recursive(recursionMode == QReadWriteLock::Recursive), currentWriter(0)
- { }
+public:
+ QReadWriteLockPrivate(bool isRecursive = false)
+ : readerCount(0), writerCount(0), waitingReaders(0), waitingWriters(0),
+ recursive(isRecursive), id(0) {}
QMutex mutex;
- QWaitCondition readerWait;
- QWaitCondition writerWait;
-
- int accessCount;
+ QWaitCondition writerCond;
+ QWaitCondition readerCond;
+ int readerCount;
+ int writerCount;
int waitingReaders;
int waitingWriters;
-
bool recursive;
+
+ //Called with the mutex locked
+ bool lockForWrite(int timeout);
+ bool lockForRead(int timeout);
+ void unlock();
+
+ //memory management
+ int id;
+ void release();
+ static QReadWriteLockPrivate *allocate();
+
+ // Recusive mutex handling
Qt::HANDLE currentWriter;
QHash<Qt::HANDLE, int> currentReaders;
+
+ // called with the mutex unlocked
+ bool recursiveLockForWrite(int timeout);
+ bool recursiveLockForRead(int timeout);
+ void recursiveUnlock();
+
};
QT_END_NAMESPACE