summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qfutex_p.h
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2017-08-17 14:52:22 -0700
committerThiago Macieira <thiago.macieira@intel.com>2017-09-18 17:39:09 +0000
commit9378bce442c523079d76cfdfcab5950d78802c9c (patch)
tree4e433c880f8b8c22e6dfe2fdd1aa31a317e4aac1 /src/corelib/thread/qfutex_p.h
parent5b5153fd5b6cc5852e4b682d1bc4a5c7979f242d (diff)
Port QSemaphore to use futexes
This is interesting because QSemaphore now needs to allocate no memory: it's just a simple 31-bit counter and the contention flag. Change-Id: I6e9274c1e7444ad48c81fffd14dbc0ab42bc2e00 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/corelib/thread/qfutex_p.h')
-rw-r--r--src/corelib/thread/qfutex_p.h21
1 files changed, 12 insertions, 9 deletions
diff --git a/src/corelib/thread/qfutex_p.h b/src/corelib/thread/qfutex_p.h
index 7831df81ea..b923bb1707 100644
--- a/src/corelib/thread/qfutex_p.h
+++ b/src/corelib/thread/qfutex_p.h
@@ -73,14 +73,12 @@ QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
namespace QtLinuxFutex {
constexpr inline bool futexAvailable() { return true; }
- inline int _q_futex(int *addr, int op, int val, const struct timespec *timeout) Q_DECL_NOTHROW
+ inline int _q_futex(int *addr, int op, int val, quintptr val2 = 0,
+ int *addr2 = nullptr, int val3 = 0) Q_DECL_NOTHROW
{
- int *addr2 = 0;
- int val2 = 0;
-
// we use __NR_futex because some libcs (like Android's bionic) don't
// provide SYS_futex etc.
- return syscall(__NR_futex, addr, op | FUTEX_PRIVATE_FLAG, val, timeout, addr2, val2);
+ return syscall(__NR_futex, addr, op | FUTEX_PRIVATE_FLAG, val, val2, addr2, val3);
}
template <typename T> int *addr(T *ptr)
{
@@ -95,7 +93,7 @@ namespace QtLinuxFutex {
template <typename Atomic>
inline void futexWait(Atomic &futex, typename Atomic::Type expectedValue)
{
- _q_futex(addr(&futex), FUTEX_WAIT, qintptr(expectedValue), nullptr);
+ _q_futex(addr(&futex), FUTEX_WAIT, qintptr(expectedValue));
}
template <typename Atomic>
inline bool futexWait(Atomic &futex, typename Atomic::Type expectedValue, qint64 nstimeout)
@@ -103,16 +101,21 @@ namespace QtLinuxFutex {
struct timespec ts;
ts.tv_sec = nstimeout / 1000 / 1000 / 1000;
ts.tv_nsec = nstimeout % (1000 * 1000 * 1000);
- int r = _q_futex(addr(&futex), FUTEX_WAIT, qintptr(expectedValue), &ts);
+ int r = _q_futex(addr(&futex), FUTEX_WAIT, qintptr(expectedValue), quintptr(&ts));
return r == 0 || errno != ETIMEDOUT;
}
template <typename Atomic> inline void futexWakeOne(Atomic &futex)
{
- _q_futex(addr(&futex), FUTEX_WAKE, 1, nullptr);
+ _q_futex(addr(&futex), FUTEX_WAKE, 1);
}
template <typename Atomic> inline void futexWakeAll(Atomic &futex)
{
- _q_futex(addr(&futex), FUTEX_WAKE, INT_MAX, nullptr);
+ _q_futex(addr(&futex), FUTEX_WAKE, INT_MAX);
+ }
+ template <typename Atomic> inline
+ void futexWakeOp(Atomic &futex1, int wake1, int wake2, Atomic &futex2, quint32 op)
+ {
+ _q_futex(addr(&futex1), FUTEX_WAKE_OP, wake1, wake2, addr(&futex2), op);
}
}
namespace QtFutex = QtLinuxFutex;