Fix performance of recursive read-write locks
The implementation used an expensive QHash to keep track of reading threads, for seemingly no good reason. Change-Id: Iffa5b18d80f56b8ff22d39aa6bc3d52c2e3ed0ef Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
4e1b09fa8f
commit
666486b3ef
@ -136,27 +136,11 @@ void QReadWriteLock::lockForRead()
|
|||||||
{
|
{
|
||||||
QMutexLocker lock(&d->mutex);
|
QMutexLocker lock(&d->mutex);
|
||||||
|
|
||||||
Qt::HANDLE self = 0;
|
|
||||||
if (d->recursive) {
|
|
||||||
self = QThread::currentThreadId();
|
|
||||||
|
|
||||||
QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self);
|
|
||||||
if (it != d->currentReaders.end()) {
|
|
||||||
++it.value();
|
|
||||||
++d->accessCount;
|
|
||||||
Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::lockForRead()",
|
|
||||||
"Overflow in lock counter");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (d->accessCount < 0 || d->waitingWriters) {
|
while (d->accessCount < 0 || d->waitingWriters) {
|
||||||
++d->waitingReaders;
|
++d->waitingReaders;
|
||||||
d->readerWait.wait(&d->mutex);
|
d->readerWait.wait(&d->mutex);
|
||||||
--d->waitingReaders;
|
--d->waitingReaders;
|
||||||
}
|
}
|
||||||
if (d->recursive)
|
|
||||||
d->currentReaders.insert(self, 1);
|
|
||||||
|
|
||||||
++d->accessCount;
|
++d->accessCount;
|
||||||
Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::lockForRead()", "Overflow in lock counter");
|
Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::lockForRead()", "Overflow in lock counter");
|
||||||
@ -182,24 +166,8 @@ bool QReadWriteLock::tryLockForRead()
|
|||||||
{
|
{
|
||||||
QMutexLocker lock(&d->mutex);
|
QMutexLocker lock(&d->mutex);
|
||||||
|
|
||||||
Qt::HANDLE self = 0;
|
|
||||||
if (d->recursive) {
|
|
||||||
self = QThread::currentThreadId();
|
|
||||||
|
|
||||||
QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self);
|
|
||||||
if (it != d->currentReaders.end()) {
|
|
||||||
++it.value();
|
|
||||||
++d->accessCount;
|
|
||||||
Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()",
|
|
||||||
"Overflow in lock counter");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d->accessCount < 0)
|
if (d->accessCount < 0)
|
||||||
return false;
|
return false;
|
||||||
if (d->recursive)
|
|
||||||
d->currentReaders.insert(self, 1);
|
|
||||||
|
|
||||||
++d->accessCount;
|
++d->accessCount;
|
||||||
Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()", "Overflow in lock counter");
|
Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()", "Overflow in lock counter");
|
||||||
@ -230,20 +198,6 @@ bool QReadWriteLock::tryLockForRead(int timeout)
|
|||||||
{
|
{
|
||||||
QMutexLocker lock(&d->mutex);
|
QMutexLocker lock(&d->mutex);
|
||||||
|
|
||||||
Qt::HANDLE self = 0;
|
|
||||||
if (d->recursive) {
|
|
||||||
self = QThread::currentThreadId();
|
|
||||||
|
|
||||||
QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self);
|
|
||||||
if (it != d->currentReaders.end()) {
|
|
||||||
++it.value();
|
|
||||||
++d->accessCount;
|
|
||||||
Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()",
|
|
||||||
"Overflow in lock counter");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (d->accessCount < 0 || d->waitingWriters) {
|
while (d->accessCount < 0 || d->waitingWriters) {
|
||||||
++d->waitingReaders;
|
++d->waitingReaders;
|
||||||
bool success = d->readerWait.wait(&d->mutex, timeout < 0 ? ULONG_MAX : ulong(timeout));
|
bool success = d->readerWait.wait(&d->mutex, timeout < 0 ? ULONG_MAX : ulong(timeout));
|
||||||
@ -251,8 +205,6 @@ bool QReadWriteLock::tryLockForRead(int timeout)
|
|||||||
if (!success)
|
if (!success)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (d->recursive)
|
|
||||||
d->currentReaders.insert(self, 1);
|
|
||||||
|
|
||||||
++d->accessCount;
|
++d->accessCount;
|
||||||
Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()", "Overflow in lock counter");
|
Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()", "Overflow in lock counter");
|
||||||
@ -412,15 +364,6 @@ void QReadWriteLock::unlock()
|
|||||||
bool unlocked = false;
|
bool unlocked = false;
|
||||||
if (d->accessCount > 0) {
|
if (d->accessCount > 0) {
|
||||||
// releasing a read lock
|
// releasing a read lock
|
||||||
if (d->recursive) {
|
|
||||||
Qt::HANDLE self = QThread::currentThreadId();
|
|
||||||
QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self);
|
|
||||||
if (it != d->currentReaders.end()) {
|
|
||||||
if (--it.value() <= 0)
|
|
||||||
d->currentReaders.erase(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unlocked = --d->accessCount == 0;
|
unlocked = --d->accessCount == 0;
|
||||||
} else if (d->accessCount < 0 && ++d->accessCount == 0) {
|
} else if (d->accessCount < 0 && ++d->accessCount == 0) {
|
||||||
// released a write lock
|
// released a write lock
|
||||||
|
@ -69,7 +69,6 @@ struct QReadWriteLockPrivate
|
|||||||
|
|
||||||
bool recursive;
|
bool recursive;
|
||||||
Qt::HANDLE currentWriter;
|
Qt::HANDLE currentWriter;
|
||||||
QHash<Qt::HANDLE, int> currentReaders;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user