diff options
author | Abseil Team <absl-team@google.com> | 2023-03-09 13:39:00 -0800 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-03-09 13:39:41 -0800 |
commit | ed8428015f1d308b65350a800dab6817763c255a (patch) | |
tree | 6bfcca32e68b8c063bbaba0d3c1517a6bf0e1e73 /absl/synchronization/internal/futex.h | |
parent | 761f04dca7fd6d27e620f09b1b170c3c5c1b3180 (diff) | |
download | abseil-ed8428015f1d308b65350a800dab6817763c255a.tar.gz abseil-ed8428015f1d308b65350a800dab6817763c255a.tar.bz2 abseil-ed8428015f1d308b65350a800dab6817763c255a.zip |
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.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; |