Simplify the futex lock loop: no need for nested while

Once we enter the inner loop, we never exit it except to return from
the lockInternal() function, so the rest is never executed again.

As a consequence of this, we won't try to fastTryLock() twice per
mutex. Therefore, for a non-recursive mutex, if lockInternal() is
entered, we'll definitely need to use futexes.

Change-Id: Ice617ed27449c1fbdc112a159a86cd0660125e13
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
This commit is contained in:
Thiago Macieira 2012-08-11 14:47:10 +02:00 committed by Qt by Nokia
parent 30bea611df
commit fc174a3728

View File

@ -126,11 +126,6 @@ bool QBasicMutex::lockInternal(int timeout) Q_DECL_NOTHROW
if (timeout >= 1)
elapsedTimer.start();
while (!fastTryLock()) {
d = d_ptr.load();
if (!d) // if d is 0, the mutex is unlocked
continue;
// the mutex is locked already, set a bit indicating we're waiting
while (d_ptr.fetchAndStoreAcquire(dummyFutexValue()) != 0) {
struct timespec ts, *pts = 0;
@ -151,9 +146,12 @@ bool QBasicMutex::lockInternal(int timeout) Q_DECL_NOTHROW
int r = _q_futex(&d_ptr, FUTEX_WAIT, quintptr(dummyFutexValue()), pts);
if (r != 0 && errno == ETIMEDOUT)
return false;
// we got woken up, so try to acquire the mutex
// note we must set to dummyFutexValue because there could be other threads
// also waiting
}
return true;
}
Q_ASSERT(d_ptr.load());
return true;
}