summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Dmitry Vyukov <dvyukov@google.com>2023-09-15 15:52:11 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2023-09-15 15:53:17 -0700
commit2c1e7e3c5c71891735f21302fb339e0d6edcd94c (patch)
tree3c50c095d1b30c335eea48c4f27928acedfb2964
parent9356553a43ae09ba7760fe7051d7100a1d8efd0b (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.cc25
-rw-r--r--absl/synchronization/mutex.h1
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;