diff options
author | Abseil Team <absl-team@google.com> | 2023-02-28 10:47:58 -0800 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-02-28 10:48:54 -0800 |
commit | 1d07cfede2d0153ebfa23543ffcc08faf55b4539 (patch) | |
tree | 4943aab47003b4119f0a97d09d932d4c6b9c8a95 /absl/synchronization/internal/futex.h | |
parent | cd43bea7779641790763f983f92683882749c647 (diff) | |
download | abseil-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.h | 70 |
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; |