summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/global/minimum-linux_p.h1
-rw-r--r--src/corelib/thread/qfutex_linux_p.h9
-rw-r--r--src/corelib/thread/qfutex_p.h5
-rw-r--r--src/corelib/thread/qfutex_win_p.h9
-rw-r--r--src/corelib/thread/qmutex.cpp15
-rw-r--r--src/corelib/thread/qsemaphore.cpp9
6 files changed, 19 insertions, 29 deletions
diff --git a/src/corelib/global/minimum-linux_p.h b/src/corelib/global/minimum-linux_p.h
index 509ad792f7..e8c872bc4a 100644
--- a/src/corelib/global/minimum-linux_p.h
+++ b/src/corelib/global/minimum-linux_p.h
@@ -35,6 +35,7 @@ QT_BEGIN_NAMESPACE
* - FUTEX_PRIVATE_FLAG 2.6.22
* - O_CLOEXEC 2.6.23
* - eventfd 2.6.23
+ * - FUTEX_WAIT_BITSET 2.6.25
* - pipe2 & dup3 2.6.27
* - accept4 2.6.28
* - renameat2 3.16 QT_CONFIG(renameat2)
diff --git a/src/corelib/thread/qfutex_linux_p.h b/src/corelib/thread/qfutex_linux_p.h
index 9291c67623..e114dfca72 100644
--- a/src/corelib/thread/qfutex_linux_p.h
+++ b/src/corelib/thread/qfutex_linux_p.h
@@ -16,10 +16,9 @@
//
#include <private/qcore_unix_p.h>
+#include <qdeadlinetimer.h>
#include <qtsan_impl.h>
-#include <chrono>
-
#include <asm/unistd.h>
#include <errno.h>
#include <limits.h>
@@ -68,10 +67,12 @@ inline void futexWait(Atomic &futex, typename Atomic::Type expectedValue)
_q_futex(addr(&futex), FUTEX_WAIT, qintptr(expectedValue));
}
template <typename Atomic>
-inline bool futexWait(Atomic &futex, typename Atomic::Type expectedValue, std::chrono::nanoseconds timeout)
+inline bool futexWait(Atomic &futex, typename Atomic::Type expectedValue, QDeadlineTimer deadline)
{
+ auto timeout = deadline.deadline<std::chrono::steady_clock>().time_since_epoch();
struct timespec ts = durationToTimespec(timeout);
- int r = _q_futex(addr(&futex), FUTEX_WAIT, qintptr(expectedValue), quintptr(&ts));
+ int r = _q_futex(addr(&futex), FUTEX_WAIT_BITSET, qintptr(expectedValue), quintptr(&ts),
+ nullptr, FUTEX_BITSET_MATCH_ANY);
return r == 0 || errno != ETIMEDOUT;
}
template <typename Atomic> inline void futexWakeOne(Atomic &futex)
diff --git a/src/corelib/thread/qfutex_p.h b/src/corelib/thread/qfutex_p.h
index 05ddede641..f7130ebad2 100644
--- a/src/corelib/thread/qfutex_p.h
+++ b/src/corelib/thread/qfutex_p.h
@@ -15,16 +15,15 @@
// We mean it.
//
+#include <qdeadlinetimer.h>
#include <private/qglobal_p.h>
-#include <chrono>
-
QT_BEGIN_NAMESPACE
namespace QtDummyFutex {
constexpr inline bool futexAvailable() { return false; }
template <typename Atomic>
- inline bool futexWait(Atomic &, typename Atomic::Type, std::chrono::nanoseconds = {})
+ inline bool futexWait(Atomic &, typename Atomic::Type, QDeadlineTimer = {})
{ Q_UNREACHABLE_RETURN(false); }
template <typename Atomic> inline void futexWakeOne(Atomic &)
{ Q_UNREACHABLE(); }
diff --git a/src/corelib/thread/qfutex_win_p.h b/src/corelib/thread/qfutex_win_p.h
index a5ce142d28..75a12bd82c 100644
--- a/src/corelib/thread/qfutex_win_p.h
+++ b/src/corelib/thread/qfutex_win_p.h
@@ -16,10 +16,9 @@
//
#include <private/qglobal_p.h>
+#include <qdeadlinetimer.h>
#include <qtsan_impl.h>
-#include <chrono>
-
#include <qt_windows.h>
#define QT_ALWAYS_USE_FUTEX
@@ -37,12 +36,10 @@ inline void futexWait(Atomic &futex, typename Atomic::Type expectedValue)
QtTsan::futexAcquire(&futex);
}
template <typename Atomic>
-inline bool futexWait(Atomic &futex, typename Atomic::Type expectedValue, std::chrono::nanoseconds timeout)
+inline bool futexWait(Atomic &futex, typename Atomic::Type expectedValue, QDeadlineTimer deadline)
{
using namespace std::chrono;
- // Using ceil so that any non-zero timeout doesn't get trunated to 0ms
- auto msecs = ceil<milliseconds>(timeout);
- BOOL r = WaitOnAddress(&futex, &expectedValue, sizeof(expectedValue), DWORD(msecs.count()));
+ BOOL r = WaitOnAddress(&futex, &expectedValue, sizeof(expectedValue), DWORD(deadline.remainingTime()));
return r || GetLastError() != ERROR_TIMEOUT;
}
template <typename Atomic> inline void futexWakeAll(Atomic &futex)
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index 7058e890e0..f1fb38118f 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -673,9 +673,7 @@ bool QBasicMutex::lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT
*/
bool QBasicMutex::lockInternal(QDeadlineTimer deadlineTimer) QT_MUTEX_LOCK_NOEXCEPT
{
- using namespace std::chrono;
- nanoseconds remainingTime = deadlineTimer.remainingTimeAsDuration();
- if (remainingTime == 0ns)
+ if (deadlineTimer.hasExpired())
return false;
if (futexAvailable()) {
@@ -691,7 +689,7 @@ bool QBasicMutex::lockInternal(QDeadlineTimer deadlineTimer) QT_MUTEX_LOCK_NOEXC
return true;
for (;;) {
- if (!futexWait(d_ptr, dummyFutexValue(), remainingTime))
+ if (!futexWait(d_ptr, dummyFutexValue(), deadlineTimer))
return false;
// We got woken up, so must try to acquire the mutex. We must set
@@ -700,9 +698,7 @@ bool QBasicMutex::lockInternal(QDeadlineTimer deadlineTimer) QT_MUTEX_LOCK_NOEXC
if (d_ptr.fetchAndStoreAcquire(dummyFutexValue()) == nullptr)
return true;
- // calculate the remaining time
- remainingTime = deadlineTimer.remainingTimeAsDuration();
- if (remainingTime == 0ns)
+ if (deadlineTimer.hasExpired())
return false;
}
}
@@ -714,7 +710,7 @@ bool QBasicMutex::lockInternal(QDeadlineTimer deadlineTimer) QT_MUTEX_LOCK_NOEXC
continue;
if (copy == dummyLocked()) {
- if (remainingTime == 0ns)
+ if (deadlineTimer.hasExpired())
return false;
// The mutex is locked but does not have a QMutexPrivate yet.
// we need to allocate a QMutexPrivate
@@ -729,7 +725,7 @@ bool QBasicMutex::lockInternal(QDeadlineTimer deadlineTimer) QT_MUTEX_LOCK_NOEXC
}
QMutexPrivate *d = static_cast<QMutexPrivate *>(copy);
- if (remainingTime == 0ns && !d->possiblyUnlocked.loadRelaxed())
+ if (deadlineTimer.hasExpired() && !d->possiblyUnlocked.loadRelaxed())
return false;
// At this point we have a pointer to a QMutexPrivate. But the other thread
@@ -791,7 +787,6 @@ bool QBasicMutex::lockInternal(QDeadlineTimer deadlineTimer) QT_MUTEX_LOCK_NOEXC
Q_ASSERT(d == d_ptr.loadRelaxed());
return true;
} else {
- Q_ASSERT(remainingTime >= 0ns);
// timed out
d->derefWaiters(1);
//There may be a race in which the mutex is unlocked right after we timed out,
diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp
index e09750581e..c472e62698 100644
--- a/src/corelib/thread/qsemaphore.cpp
+++ b/src/corelib/thread/qsemaphore.cpp
@@ -149,7 +149,6 @@ futexSemaphoreTryAcquire_loop(QBasicAtomicInteger<quintptr> &u, quintptr curValu
QDeadlineTimer timer)
{
using namespace std::chrono;
- nanoseconds remainingTime = IsTimed ? timer.remainingTimeAsDuration() : -1ns;
int n = int(unsigned(nn));
// we're called after one testAndSet, so start by waiting first
@@ -166,8 +165,8 @@ futexSemaphoreTryAcquire_loop(QBasicAtomicInteger<quintptr> &u, quintptr curValu
}
}
- if (IsTimed && remainingTime > 0ns) {
- bool timedout = !futexWait(*ptr, curValue, remainingTime);
+ if (IsTimed) {
+ bool timedout = !futexWait(*ptr, curValue, timer);
if (timedout)
return false;
} else {
@@ -175,8 +174,6 @@ futexSemaphoreTryAcquire_loop(QBasicAtomicInteger<quintptr> &u, quintptr curValu
}
curValue = u.loadAcquire();
- if (IsTimed)
- remainingTime = timer.remainingTimeAsDuration();
// try to acquire
while (futexAvailCounter(curValue) >= n) {
@@ -186,7 +183,7 @@ futexSemaphoreTryAcquire_loop(QBasicAtomicInteger<quintptr> &u, quintptr curValu
}
// not enough tokens available, put us to wait
- if (IsTimed && remainingTime == 0ns)
+ if (IsTimed && timer.hasExpired())
return false;
}
}