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>
This commit is contained in:
parent
870bd84a4e
commit
30bea611df
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user