summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2012-08-11 16:45:14 +0200
committerQt by Nokia <qt-info@nokia.com>2012-09-14 03:45:50 +0200
commit30bea611df2d95b53b63273ac867d9bd0a181edf (patch)
tree1d34c3cdf9294d649e02d45a13f46e731b5f9963 /src/corelib/thread
parent870bd84a4ee53ea98fd232da18771b1525dac1a1 (diff)
Make QBasicMutex be exclusively non-recursive
Dispatch to the recursive mutex functions from QMutex::lock, tryLock and unlock. This has the benefit that those using QBasicMutex will not go through the testing for recursive mutexes. It simplifies a little the code for those users. For the users of QMutex, the code required to perform a lock does not appear to change. Change-Id: I0ca9965e012b283c30f1fab8e9f6d9b3288c2247 Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Diffstat (limited to 'src/corelib/thread')
-rw-r--r--src/corelib/thread/qmutex.cpp60
-rw-r--r--src/corelib/thread/qmutex.h6
-rw-r--r--src/corelib/thread/qmutex_linux.cpp20
-rw-r--r--src/corelib/thread/qmutex_p.h1
4 files changed, 52 insertions, 35 deletions
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index fa4fddca56..2906a5a198 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2012 Intel Corporation
** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -55,6 +56,19 @@
QT_BEGIN_NAMESPACE
+static inline bool isRecursive(QMutexData *d)
+{
+ register quintptr u = quintptr(d);
+ if (Q_LIKELY(u <= 0x3))
+ return false;
+#ifdef QT_LINUX_FUTEX
+ Q_ASSERT(d->recursive);
+ return true;
+#else
+ return d->recursive;
+#endif
+}
+
/*
\class QBasicMutex
\inmodule QtCore
@@ -180,7 +194,13 @@ QMutex::~QMutex()
*/
void QMutex::lock() QT_MUTEX_LOCK_NOEXCEPT
{
- QBasicMutex::lock();
+ if (fastTryLock())
+ return;
+ QMutexData *current = d_ptr.loadAcquire();
+ if (QT_PREPEND_NAMESPACE(isRecursive)(current))
+ static_cast<QRecursiveMutexPrivate *>(current)->lock(-1);
+ else
+ lockInternal();
}
/*! \fn bool QMutex::tryLock(int timeout)
@@ -208,7 +228,13 @@ void QMutex::lock() QT_MUTEX_LOCK_NOEXCEPT
*/
bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
{
- return QBasicMutex::tryLock(timeout);
+ if (fastTryLock())
+ return true;
+ QMutexData *current = d_ptr.loadAcquire();
+ if (QT_PREPEND_NAMESPACE(isRecursive)(current))
+ return static_cast<QRecursiveMutexPrivate *>(current)->lock(timeout);
+ else
+ return lockInternal(timeout);
}
/*! \fn void QMutex::unlock()
@@ -220,7 +246,13 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
*/
void QMutex::unlock() Q_DECL_NOTHROW
{
- QBasicMutex::unlock();
+ if (fastTryUnlock())
+ return;
+ QMutexData *current = d_ptr.loadAcquire();
+ if (QT_PREPEND_NAMESPACE(isRecursive)(current))
+ static_cast<QRecursiveMutexPrivate *>(current)->unlock();
+ else
+ unlockInternal();
}
/*!
@@ -230,16 +262,9 @@ void QMutex::unlock() Q_DECL_NOTHROW
Returns true if the mutex is recursive
*/
-bool QBasicMutex::isRecursive() {
- QMutexData *d = d_ptr.load();
- if (quintptr(d) <= 0x3)
- return false;
-#ifdef QT_LINUX_FUTEX
- Q_ASSERT(d->recursive);
- return true;
-#else
- return d->recursive;
-#endif
+bool QBasicMutex::isRecursive()
+{
+ return QT_PREPEND_NAMESPACE(isRecursive)(d_ptr.loadAcquire());
}
@@ -338,8 +363,7 @@ bool QBasicMutex::isRecursive() {
*/
bool QBasicMutex::lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT
{
- if (isRecursive())
- return static_cast<QRecursiveMutexPrivate *>(d_ptr.load())->lock(timeout);
+ Q_ASSERT(!isRecursive());
while (!fastTryLock()) {
QMutexData *copy = d_ptr.loadAcquire();
@@ -435,11 +459,7 @@ void QBasicMutex::unlockInternal() Q_DECL_NOTHROW
QMutexData *copy = d_ptr.loadAcquire();
Q_ASSERT(copy); //we must be locked
Q_ASSERT(copy != dummyLocked()); // testAndSetRelease(dummyLocked(), 0) failed
-
- if (copy->recursive) {
- static_cast<QRecursiveMutexPrivate *>(copy)->unlock();
- return;
- }
+ Q_ASSERT(!isRecursive());
QMutexPrivate *d = reinterpret_cast<QMutexPrivate *>(copy);
diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h
index 5d4d6969f5..dd718c4796 100644
--- a/src/corelib/thread/qmutex.h
+++ b/src/corelib/thread/qmutex.h
@@ -71,7 +71,7 @@ public:
inline void unlock() Q_DECL_NOTHROW {
Q_ASSERT(d_ptr.load()); //mutex must be locked
- if (!d_ptr.testAndSetRelease(dummyLocked(), 0))
+ if (!fastTryUnlock())
unlockInternal();
}
@@ -85,6 +85,10 @@ private:
inline bool fastTryLock() Q_DECL_NOTHROW {
return d_ptr.testAndSetAcquire(0, dummyLocked());
}
+ inline bool fastTryUnlock() Q_DECL_NOTHROW {
+ return d_ptr.testAndSetRelease(dummyLocked(), 0);
+ }
+
bool lockInternal(int timeout = -1) QT_MUTEX_LOCK_NOEXCEPT;
void unlockInternal() Q_DECL_NOTHROW;
diff --git a/src/corelib/thread/qmutex_linux.cpp b/src/corelib/thread/qmutex_linux.cpp
index 09db046f0f..a17e9d0a24 100644
--- a/src/corelib/thread/qmutex_linux.cpp
+++ b/src/corelib/thread/qmutex_linux.cpp
@@ -116,13 +116,9 @@ static inline QMutexData *dummyFutexValue()
bool QBasicMutex::lockInternal(int timeout) Q_DECL_NOTHROW
{
- // we're here because fastTryLock() has just failed
- QMutexData *d = d_ptr.load();
- if (quintptr(d) > 0x3) { //d == dummyLocked() || d == dummyFutexValue()
- Q_ASSERT(d->recursive);
- return static_cast<QRecursiveMutexPrivate *>(d)->lock(timeout);
- }
+ Q_ASSERT(!isRecursive());
+ // we're here because fastTryLock() has just failed
if (timeout == 0)
return false;
@@ -167,15 +163,11 @@ void QBasicMutex::unlockInternal() Q_DECL_NOTHROW
QMutexData *d = d_ptr.load();
Q_ASSERT(d); //we must be locked
Q_ASSERT(d != dummyLocked()); // testAndSetRelease(dummyLocked(), 0) failed
+ Q_UNUSED(d);
+ Q_ASSERT(!isRecursive());
- if (d == dummyFutexValue()) {
- d_ptr.fetchAndStoreRelease(0);
- _q_futex(&d_ptr, FUTEX_WAKE, 1, 0);
- return;
- }
-
- Q_ASSERT(d->recursive);
- static_cast<QRecursiveMutexPrivate *>(d)->unlock();
+ d_ptr.fetchAndStoreRelease(0);
+ _q_futex(&d_ptr, FUTEX_WAKE, 1, 0);
}
diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h
index 3ef99d5fc0..f51dd0e9e3 100644
--- a/src/corelib/thread/qmutex_p.h
+++ b/src/corelib/thread/qmutex_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2012 Intel Corporation
** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.