diff options
author | Derek Mauro <dmauro@google.com> | 2023-04-06 08:19:11 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-04-06 08:19:57 -0700 |
commit | a880427b38b2eca647a6eb0a09b241dbd962a4b9 (patch) | |
tree | 78b48493f26979a7ac308554372399e7e57b7440 /absl | |
parent | d7228036ab2a191462c532b914a99c3a8d10a171 (diff) |
Synchronization: Support true relative timeouts on Apple platforms
using the non-portable pthread_cond_timedwait_relative_np()
PiperOrigin-RevId: 522340555
Change-Id: I08682f74d8d94965330f12274c7a92632b1a29f1
Diffstat (limited to 'absl')
-rw-r--r-- | absl/synchronization/internal/pthread_waiter.cc | 35 | ||||
-rw-r--r-- | absl/synchronization/internal/pthread_waiter.h | 2 |
2 files changed, 31 insertions, 6 deletions
diff --git a/absl/synchronization/internal/pthread_waiter.cc b/absl/synchronization/internal/pthread_waiter.cc index 52587827..a8dafd94 100644 --- a/absl/synchronization/internal/pthread_waiter.cc +++ b/absl/synchronization/internal/pthread_waiter.cc @@ -20,6 +20,7 @@ #include <sys/time.h> #include <unistd.h> +#include <cassert> #include <cerrno> #include "absl/base/config.h" @@ -73,12 +74,34 @@ PthreadWaiter::PthreadWaiter() : waiter_count_(0), wakeup_count_(0) { } } -bool PthreadWaiter::Wait(KernelTimeout t) { - struct timespec abs_timeout; - if (t.has_timeout()) { - abs_timeout = t.MakeAbsTimespec(); +#ifdef __APPLE__ +#define ABSL_INTERNAL_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 1 +#endif + +// Calls pthread_cond_timedwait() or possibly something else like +// pthread_cond_timedwait_relative_np() depending on the platform and +// KernelTimeout requested. The return value is the same as the return +// value of pthread_cond_timedwait(). +int PthreadWaiter::TimedWait(KernelTimeout t) { +#ifndef __GOOGLE_GRTE_VERSION__ + constexpr bool kRelativeTimeoutSupported = true; +#else + constexpr bool kRelativeTimeoutSupported = false; +#endif + + assert(t.has_timeout()); + if (kRelativeTimeoutSupported && t.is_relative_timeout()) { +#ifdef ABSL_INTERNAL_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP + const auto rel_timeout = t.MakeRelativeTimespec(); + return pthread_cond_timedwait_relative_np(&cv_, &mu_, &rel_timeout); +#endif } + const auto abs_timeout = t.MakeAbsTimespec(); + return pthread_cond_timedwait(&cv_, &mu_, &abs_timeout); +} + +bool PthreadWaiter::Wait(KernelTimeout t) { PthreadMutexHolder h(&mu_); ++waiter_count_; // Loop until we find a wakeup to consume or timeout. @@ -94,13 +117,13 @@ bool PthreadWaiter::Wait(KernelTimeout t) { ABSL_RAW_LOG(FATAL, "pthread_cond_wait failed: %d", err); } } else { - const int err = pthread_cond_timedwait(&cv_, &mu_, &abs_timeout); + const int err = TimedWait(t); if (err == ETIMEDOUT) { --waiter_count_; return false; } if (err != 0) { - ABSL_RAW_LOG(FATAL, "pthread_cond_timedwait failed: %d", err); + ABSL_RAW_LOG(FATAL, "PthreadWaiter::TimedWait() failed: %d", err); } } first_pass = false; diff --git a/absl/synchronization/internal/pthread_waiter.h b/absl/synchronization/internal/pthread_waiter.h index a930a9e8..206aefa4 100644 --- a/absl/synchronization/internal/pthread_waiter.h +++ b/absl/synchronization/internal/pthread_waiter.h @@ -40,6 +40,8 @@ class PthreadWaiter : public WaiterCrtp<PthreadWaiter> { static constexpr char kName[] = "PthreadWaiter"; private: + int TimedWait(KernelTimeout t); + // REQUIRES: mu_ must be held. void InternalCondVarPoke(); |