aboutsummaryrefslogtreecommitdiff
path: root/absl/synchronization/internal/futex.h
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2023-02-28 10:47:58 -0800
committerCopybara-Service <copybara-worker@google.com>2023-02-28 10:48:54 -0800
commit1d07cfede2d0153ebfa23543ffcc08faf55b4539 (patch)
tree4943aab47003b4119f0a97d09d932d4c6b9c8a95 /absl/synchronization/internal/futex.h
parentcd43bea7779641790763f983f92683882749c647 (diff)
downloadabseil-1d07cfede2d0153ebfa23543ffcc08faf55b4539.tar.gz
abseil-1d07cfede2d0153ebfa23543ffcc08faf55b4539.tar.bz2
abseil-1d07cfede2d0153ebfa23543ffcc08faf55b4539.zip
Rollback because of internal incompatibility.
PiperOrigin-RevId: 512979517 Change-Id: I7fe38ed246e42e6f8eb322e15c3b299215163168
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;