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 /absl/synchronization/mutex.cc | |
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
Diffstat (limited to 'absl/synchronization/mutex.cc')
-rw-r--r-- | absl/synchronization/mutex.cc | 25 |
1 files changed, 4 insertions, 21 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); } |