summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2023-09-08 02:30:31 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2023-09-08 02:31:35 -0700
commit38afe317694fcc11fa9f4b27bd930023719cf699 (patch)
treef874c340383677a40818807766172ee1cd9754e4
parent3cb94be9bea2eda6dd2d572d1cf074efcc48a20b (diff)
absl: remove special handling of Condition::kTrue
Condition::kTrue is used very rarely (frequently its uses even indicate confusion and bugs). But we pay few additional branches for kTrue on all Condition operations. Remove that special handling and simplify logic. PiperOrigin-RevId: 563691160 Change-Id: I76125adde4872489da069dd9c894ed73a65d1d83
-rw-r--r--absl/synchronization/mutex.cc25
-rw-r--r--absl/synchronization/mutex.h8
2 files changed, 12 insertions, 21 deletions
diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc
index 353a8280..9a25570c 100644
--- a/absl/synchronization/mutex.cc
+++ b/absl/synchronization/mutex.cc
@@ -966,8 +966,7 @@ static PerThreadSynch* Enqueue(PerThreadSynch* head, SynchWaitParams* waitp,
} while (s->priority <= advance_to->priority);
// termination guaranteed because s->priority > head->priority
// and head is the end of a skip chain
- } else if (waitp->how == kExclusive &&
- Condition::GuaranteedEqual(waitp->cond, nullptr)) {
+ } else if (waitp->how == kExclusive && waitp->cond == nullptr) {
// An unlocker could be scanning the queue, but we know it will recheck
// the queue front for writers that have no condition, which is what s
// is, so an insert at front is safe.
@@ -1627,15 +1626,11 @@ bool Mutex::AwaitCommon(const Condition& cond, KernelTimeout t) {
SynchWaitParams waitp(how, &cond, t, nullptr /*no cvmu*/,
Synch_GetPerThreadAnnotated(this),
nullptr /*no cv_word*/);
- int flags = kMuHasBlocked;
- if (!Condition::GuaranteedEqual(&cond, nullptr)) {
- flags |= kMuIsCond;
- }
this->UnlockSlow(&waitp);
this->Block(waitp.thread);
ABSL_TSAN_MUTEX_POST_UNLOCK(this, TsanFlags(how));
ABSL_TSAN_MUTEX_PRE_LOCK(this, TsanFlags(how));
- this->LockSlowLoop(&waitp, flags);
+ this->LockSlowLoop(&waitp, kMuHasBlocked | kMuIsCond);
bool res = waitp.cond != nullptr || // => cond known true from LockSlowLoop
EvalConditionAnnotated(&cond, this, true, false, how == kShared);
ABSL_TSAN_MUTEX_POST_LOCK(this, TsanFlags(how), 0);
@@ -1917,7 +1912,7 @@ bool Mutex::LockSlowWithDeadline(MuHow how, const Condition* cond,
SynchWaitParams waitp(how, cond, t, nullptr /*no cvmu*/,
Synch_GetPerThreadAnnotated(this),
nullptr /*no cv_word*/);
- if (!Condition::GuaranteedEqual(cond, nullptr)) {
+ if (cond != nullptr) {
flags |= kMuIsCond;
}
if (unlock) {
@@ -2211,7 +2206,7 @@ ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams* waitp) {
}
}
if (h->next->waitp->how == kExclusive &&
- Condition::GuaranteedEqual(h->next->waitp->cond, nullptr)) {
+ h->next->waitp->cond == nullptr) {
// easy case: writer with no condition; no need to search
pw = h; // wake w, the successor of h (=pw)
w = h->next;
@@ -2815,17 +2810,11 @@ Condition::Condition(const bool* cond)
StoreCallback(dereference);
}
-bool Condition::Eval() const {
- // eval_ == null for kTrue
- return (this->eval_ == nullptr) || (*this->eval_)(this);
-}
+bool Condition::Eval() const { return (*this->eval_)(this); }
bool Condition::GuaranteedEqual(const Condition* a, const Condition* b) {
- // kTrue logic.
- if (a == nullptr || a->eval_ == nullptr) {
- return b == nullptr || b->eval_ == nullptr;
- } else if (b == nullptr || b->eval_ == nullptr) {
- return false;
+ if (a == nullptr || b == nullptr) {
+ return a == nullptr && b == nullptr;
}
// Check equality of the representative fields.
return a->eval_ == b->eval_ && a->arg_ == b->arg_ &&
diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h
index 645c26d9..f2bafa97 100644
--- a/absl/synchronization/mutex.h
+++ b/absl/synchronization/mutex.h
@@ -807,10 +807,10 @@ class Condition {
#endif
// Function with which to evaluate callbacks and/or arguments.
- bool (*eval_)(const Condition*) = nullptr;
+ bool (*const eval_)(const Condition*);
// Either an argument for a function call or an object for a method call.
- void* arg_ = nullptr;
+ void* const arg_;
// Various functions eval_ can point to:
static bool CallVoidPtrFunction(const Condition*);
@@ -833,8 +833,10 @@ class Condition {
std::memcpy(callback, callback_, sizeof(*callback));
}
+ static bool AlwaysTrue(const Condition*) { return true; }
+
// Used only to create kTrue.
- constexpr Condition() = default;
+ constexpr Condition() : eval_(AlwaysTrue), arg_(nullptr) {}
};
// -----------------------------------------------------------------------------