summaryrefslogtreecommitdiff
path: root/absl/synchronization/mutex.cc
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 /absl/synchronization/mutex.cc
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
Diffstat (limited to 'absl/synchronization/mutex.cc')
-rw-r--r--absl/synchronization/mutex.cc25
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);
}