Avoid calling QElapsedTimer::nsecsElapsed before the first futex sleep
authorThiago Macieira <thiago.macieira@intel.com>
Sat, 11 Aug 2012 14:03:51 +0000 (16:03 +0200)
committerQt by Nokia <qt-info@nokia.com>
Fri, 14 Sep 2012 01:45:50 +0000 (03:45 +0200)
The first time we're going to sleep, the timeout should be exactly the
value that was passed by the user. We don't need to calculate the time
elapsed between start() and a few lines below.

Change-Id: I99c363b6f0ecfd07ad787b79b75e61771733c2b3
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
src/corelib/thread/qmutex_linux.cpp

index 0c44d18..e2842a6 100644 (file)
@@ -184,15 +184,18 @@ bool lockInternal_helper(QBasicAtomicPointer<QMutexData> &d_ptr, int timeout = -
     if (timeout == 0)
         return false;
 
+    struct timespec ts, *pts = 0;
     QElapsedTimer elapsedTimer;
     checkElapsedTimerIsTrivial();
-    if (IsTimed)
+    if (IsTimed) {
+        ts.tv_sec = timeout / Q_INT64_C(1000) / 1000 / 1000;
+        ts.tv_nsec = timeout % Q_INT64_C(1000) * 1000 * 1000;
         elapsedTimer.start();
+    }
 
     // the mutex is locked already, set a bit indicating we're waiting
     while (d_ptr.fetchAndStoreAcquire(dummyFutexValue()) != 0) {
-        struct timespec ts, *pts = 0;
-        if (IsTimed) {
+        if (IsTimed && pts == &ts) {
             // recalculate the timeout
             qint64 xtimeout = qint64(timeout) * 1000 * 1000;
             xtimeout -= elapsedTimer.nsecsElapsed();
@@ -202,8 +205,9 @@ bool lockInternal_helper(QBasicAtomicPointer<QMutexData> &d_ptr, int timeout = -
             }
             ts.tv_sec = xtimeout / Q_INT64_C(1000) / 1000 / 1000;
             ts.tv_nsec = xtimeout % (Q_INT64_C(1000) * 1000 * 1000);
-            pts = &ts;
         }
+        if (IsTimed)
+            pts = &ts;
 
         // successfully set the waiting bit, now sleep
         int r = _q_futex(&d_ptr, FUTEX_WAIT, quintptr(dummyFutexValue()), pts);