diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2023-09-15 15:52:11 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-09-15 15:53:17 -0700 |
commit | 2c1e7e3c5c71891735f21302fb339e0d6edcd94c (patch) | |
tree | 3c50c095d1b30c335eea48c4f27928acedfb2964 | |
parent | 9356553a43ae09ba7760fe7051d7100a1d8efd0b (diff) |
absl: remove special case for timed CondVar waits
CondVar wait morhping has a special case for timed waits.
The code goes back to 2006, it seems that there might have
been some reasons to do this back then.
But now it does not seem to be necessary.
Wait morphing should work just fine after timed CondVar waits.
Remove the special case and simplify code.
PiperOrigin-RevId: 565798838
Change-Id: I4e4d61ae7ebd521f5c32dfc673e57a0c245e7cfb
-rw-r--r-- | absl/synchronization/mutex.cc | 25 | ||||
-rw-r--r-- | absl/synchronization/mutex.h | 1 |
2 files changed, 4 insertions, 22 deletions
diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc index 8148fbde..ad9e2894 100644 --- a/absl/synchronization/mutex.cc +++ b/absl/synchronization/mutex.cc @@ -2325,10 +2325,10 @@ void Mutex::Fer(PerThreadSynch* w) { int c = 0; ABSL_RAW_CHECK(w->waitp->cond == nullptr, "Mutex::Fer while waiting on Condition"); - ABSL_RAW_CHECK(!w->waitp->timeout.has_timeout(), - "Mutex::Fer while in timed wait"); ABSL_RAW_CHECK(w->waitp->cv_word == nullptr, "Mutex::Fer with pending CondVar queueing"); + // The CondVar timeout is not relevant for the Mutex wait. + w->waitp->timeout = {}; for (;;) { intptr_t v = mu_.load(std::memory_order_relaxed); // Note: must not queue if the mutex is unlocked (nobody will wake it). @@ -2571,23 +2571,6 @@ bool CondVar::WaitCommon(Mutex* mutex, KernelTimeout t) { return rc; } -// Wake thread w -// If it was a timed wait, w will be waiting on w->cv -// Otherwise, if it was not a Mutex mutex, w will be waiting on w->sem -// Otherwise, w is transferred to the Mutex mutex via Mutex::Fer(). -void CondVar::Wakeup(PerThreadSynch* w) { - if (w->waitp->timeout.has_timeout()) { - // The waiting thread only needs to observe "w->state == kAvailable" to be - // released, we must cache "cvmu" before clearing "next". - Mutex* mu = w->waitp->cvmu; - w->next = nullptr; - w->state.store(PerThreadSynch::kAvailable, std::memory_order_release); - Mutex::IncrementSynchSem(mu, w); - } else { - w->waitp->cvmu->Fer(w); - } -} - void CondVar::Signal() { SchedulingGuard::ScopedDisable disable_rescheduling; ABSL_TSAN_MUTEX_PRE_SIGNAL(nullptr, 0); @@ -2612,7 +2595,7 @@ void CondVar::Signal() { cv_.store((v & kCvEvent) | reinterpret_cast<intptr_t>(h), std::memory_order_release); if (w != nullptr) { - CondVar::Wakeup(w); // wake waiter, if there was one + w->waitp->cvmu->Fer(w); // wake waiter, if there was one cond_var_tracer("Signal wakeup", this); } if ((v & kCvEvent) != 0) { @@ -2648,7 +2631,7 @@ void CondVar::SignalAll() { do { // for every thread, wake it up w = n; n = n->next; - CondVar::Wakeup(w); + w->waitp->cvmu->Fer(w); } while (w != h); cond_var_tracer("SignalAll wakeup", this); } diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h index 1fb6cca1..d146b066 100644 --- a/absl/synchronization/mutex.h +++ b/absl/synchronization/mutex.h @@ -974,7 +974,6 @@ class CondVar { private: bool WaitCommon(Mutex* mutex, synchronization_internal::KernelTimeout t); void Remove(base_internal::PerThreadSynch* s); - void Wakeup(base_internal::PerThreadSynch* w); std::atomic<intptr_t> cv_; // Condition variable state. CondVar(const CondVar&) = delete; CondVar& operator=(const CondVar&) = delete; |