summaryrefslogtreecommitdiff
path: root/absl/synchronization/internal/futex.h
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2023-03-09 13:39:00 -0800
committerGravatar Copybara-Service <copybara-worker@google.com>2023-03-09 13:39:41 -0800
commited8428015f1d308b65350a800dab6817763c255a (patch)
tree6bfcca32e68b8c063bbaba0d3c1517a6bf0e1e73 /absl/synchronization/internal/futex.h
parent761f04dca7fd6d27e620f09b1b170c3c5c1b3180 (diff)
Rollback Mutex relative timeout support because of internal incompatibility
PiperOrigin-RevId: 515427893 Change-Id: I89e8756fcf400459b0226d14785c6511ad3e380b
Diffstat (limited to 'absl/synchronization/internal/futex.h')
-rw-r--r--absl/synchronization/internal/futex.h70
1 files changed, 23 insertions, 47 deletions
diff --git a/absl/synchronization/internal/futex.h b/absl/synchronization/internal/futex.h
index 62bb40f7..9cf9841d 100644
--- a/absl/synchronization/internal/futex.h
+++ b/absl/synchronization/internal/futex.h
@@ -16,7 +16,9 @@
#include "absl/base/config.h"
-#ifndef _WIN32
+#ifdef _WIN32
+#include <windows.h>
+#else
#include <sys/time.h>
#include <unistd.h>
#endif
@@ -83,60 +85,34 @@ namespace synchronization_internal {
class FutexImpl {
public:
- // Atomically check that `*v == val`, and if it is, then sleep until the
- // timeout `t` has been reached, or until woken by `Wake()`.
- static int WaitUntil(std::atomic<int32_t>* v, int32_t val,
+ static int WaitUntil(std::atomic<int32_t> *v, int32_t val,
KernelTimeout t) {
- if (!t.has_timeout()) {
- return Wait(v, val);
- } else if (t.is_absolute_timeout()) {
- auto abs_timespec = t.MakeAbsTimespec();
- return WaitAbsoluteTimeout(v, val, &abs_timespec);
+ long err = 0; // NOLINT(runtime/int)
+ if (t.has_timeout()) {
+ // https://locklessinc.com/articles/futex_cheat_sheet/
+ // Unlike FUTEX_WAIT, FUTEX_WAIT_BITSET uses absolute time.
+ struct timespec abs_timeout = t.MakeAbsTimespec();
+ // Atomically check that the futex value is still 0, and if it
+ // is, sleep until abs_timeout or until woken by FUTEX_WAKE.
+ err = syscall(
+ SYS_futex, reinterpret_cast<int32_t *>(v),
+ FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME, val,
+ &abs_timeout, nullptr, FUTEX_BITSET_MATCH_ANY);
} else {
- auto rel_timespec = t.MakeRelativeTimespec();
- return WaitRelativeTimeout(v, val, &rel_timespec);
+ // Atomically check that the futex value is still 0, and if it
+ // is, sleep until woken by FUTEX_WAKE.
+ err = syscall(SYS_futex, reinterpret_cast<int32_t *>(v),
+ FUTEX_WAIT | FUTEX_PRIVATE_FLAG, val, nullptr);
}
- }
-
- // Atomically check that `*v == val`, and if it is, then sleep until the until
- // woken by `Wake()`.
- static int Wait(std::atomic<int32_t>* v, int32_t val) {
- return WaitAbsoluteTimeout(v, val, nullptr);
- }
-
- // Atomically check that `*v == val`, and if it is, then sleep until
- // CLOCK_REALTIME reaches `*abs_timeout`, or until woken by `Wake()`.
- static int WaitAbsoluteTimeout(std::atomic<int32_t>* v, int32_t val,
- const struct timespec* abs_timeout) {
- // https://locklessinc.com/articles/futex_cheat_sheet/
- // Unlike FUTEX_WAIT, FUTEX_WAIT_BITSET uses absolute time.
- auto err =
- syscall(SYS_futex, reinterpret_cast<int32_t*>(v),
- FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME,
- val, abs_timeout, nullptr, FUTEX_BITSET_MATCH_ANY);
- if (err != 0) {
- return -errno;
- }
- return 0;
- }
-
- // Atomically check that `*v == val`, and if it is, then sleep until
- // `*rel_timeout` has elapsed, or until woken by `Wake()`.
- static int WaitRelativeTimeout(std::atomic<int32_t>* v, int32_t val,
- const struct timespec* rel_timeout) {
- // Atomically check that the futex value is still 0, and if it
- // is, sleep until abs_timeout or until woken by FUTEX_WAKE.
- auto err = syscall(SYS_futex, reinterpret_cast<int32_t*>(v),
- FUTEX_PRIVATE_FLAG, val, rel_timeout);
- if (err != 0) {
+ if (ABSL_PREDICT_FALSE(err != 0)) {
return -errno;
}
return 0;
}
- // Wakes at most `count` waiters that have entered the sleep state on `v`.
- static int Wake(std::atomic<int32_t>* v, int32_t count) {
- auto err = syscall(SYS_futex, reinterpret_cast<int32_t*>(v),
+ static int Wake(std::atomic<int32_t> *v, int32_t count) {
+ // NOLINTNEXTLINE(runtime/int)
+ long err = syscall(SYS_futex, reinterpret_cast<int32_t*>(v),
FUTEX_WAKE | FUTEX_PRIVATE_FLAG, count);
if (ABSL_PREDICT_FALSE(err < 0)) {
return -errno;