Commit 792e55fc by Abseil Team Committed by Copybara-Service

Rollback:

absl: remove special handling of Condition::kTrue
absl: remove known_false condition in Mutex code
There are some test breakages.

PiperOrigin-RevId: 563751370
Change-Id: Ie14dc799e0a0d286a7e1b47f0a9bbe59dfb23f70
parent 6644e5bb
...@@ -960,7 +960,8 @@ static PerThreadSynch* Enqueue(PerThreadSynch* head, SynchWaitParams* waitp, ...@@ -960,7 +960,8 @@ static PerThreadSynch* Enqueue(PerThreadSynch* head, SynchWaitParams* waitp,
} while (s->priority <= advance_to->priority); } while (s->priority <= advance_to->priority);
// termination guaranteed because s->priority > head->priority // termination guaranteed because s->priority > head->priority
// and head is the end of a skip chain // and head is the end of a skip chain
} else if (waitp->how == kExclusive && waitp->cond == nullptr) { } else if (waitp->how == kExclusive &&
Condition::GuaranteedEqual(waitp->cond, nullptr)) {
// An unlocker could be scanning the queue, but we know it will recheck // 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 // the queue front for writers that have no condition, which is what s
// is, so an insert at front is safe. // is, so an insert at front is safe.
...@@ -1541,11 +1542,15 @@ bool Mutex::AwaitCommon(const Condition& cond, KernelTimeout t) { ...@@ -1541,11 +1542,15 @@ bool Mutex::AwaitCommon(const Condition& cond, KernelTimeout t) {
SynchWaitParams waitp(how, &cond, t, nullptr /*no cvmu*/, SynchWaitParams waitp(how, &cond, t, nullptr /*no cvmu*/,
Synch_GetPerThreadAnnotated(this), Synch_GetPerThreadAnnotated(this),
nullptr /*no cv_word*/); nullptr /*no cv_word*/);
int flags = kMuHasBlocked;
if (!Condition::GuaranteedEqual(&cond, nullptr)) {
flags |= kMuIsCond;
}
this->UnlockSlow(&waitp); this->UnlockSlow(&waitp);
this->Block(waitp.thread); this->Block(waitp.thread);
ABSL_TSAN_MUTEX_POST_UNLOCK(this, TsanFlags(how)); ABSL_TSAN_MUTEX_POST_UNLOCK(this, TsanFlags(how));
ABSL_TSAN_MUTEX_PRE_LOCK(this, TsanFlags(how)); ABSL_TSAN_MUTEX_PRE_LOCK(this, TsanFlags(how));
this->LockSlowLoop(&waitp, kMuHasBlocked | kMuIsCond); this->LockSlowLoop(&waitp, flags);
bool res = waitp.cond != nullptr || // => cond known true from LockSlowLoop bool res = waitp.cond != nullptr || // => cond known true from LockSlowLoop
EvalConditionAnnotated(&cond, this, true, false, how == kShared); EvalConditionAnnotated(&cond, this, true, false, how == kShared);
ABSL_TSAN_MUTEX_POST_LOCK(this, TsanFlags(how), 0); ABSL_TSAN_MUTEX_POST_LOCK(this, TsanFlags(how), 0);
...@@ -1829,7 +1834,7 @@ bool Mutex::LockSlowWithDeadline(MuHow how, const Condition* cond, ...@@ -1829,7 +1834,7 @@ bool Mutex::LockSlowWithDeadline(MuHow how, const Condition* cond,
SynchWaitParams waitp(how, cond, t, nullptr /*no cvmu*/, SynchWaitParams waitp(how, cond, t, nullptr /*no cvmu*/,
Synch_GetPerThreadAnnotated(this), Synch_GetPerThreadAnnotated(this),
nullptr /*no cv_word*/); nullptr /*no cv_word*/);
if (cond != nullptr) { if (!Condition::GuaranteedEqual(cond, nullptr)) {
flags |= kMuIsCond; flags |= kMuIsCond;
} }
if (unlock) { if (unlock) {
...@@ -2019,6 +2024,7 @@ ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams* waitp) { ...@@ -2019,6 +2024,7 @@ ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams* waitp) {
// head of the list searched previously, or zero // head of the list searched previously, or zero
PerThreadSynch* old_h = nullptr; PerThreadSynch* old_h = nullptr;
// a condition that's known to be false. // a condition that's known to be false.
const Condition* known_false = nullptr;
PerThreadSynch* wake_list = kPerThreadSynchNull; // list of threads to wake PerThreadSynch* wake_list = kPerThreadSynchNull; // list of threads to wake
intptr_t wr_wait = 0; // set to kMuWrWait if we wake a reader and a intptr_t wr_wait = 0; // set to kMuWrWait if we wake a reader and a
// later writer could have acquired the lock // later writer could have acquired the lock
...@@ -2122,7 +2128,7 @@ ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams* waitp) { ...@@ -2122,7 +2128,7 @@ ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams* waitp) {
} }
} }
if (h->next->waitp->how == kExclusive && if (h->next->waitp->how == kExclusive &&
h->next->waitp->cond == nullptr) { Condition::GuaranteedEqual(h->next->waitp->cond, nullptr)) {
// easy case: writer with no condition; no need to search // easy case: writer with no condition; no need to search
pw = h; // wake w, the successor of h (=pw) pw = h; // wake w, the successor of h (=pw)
w = h->next; w = h->next;
...@@ -2205,8 +2211,10 @@ ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams* waitp) { ...@@ -2205,8 +2211,10 @@ ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams* waitp) {
w_walk->wake = false; w_walk->wake = false;
if (w_walk->waitp->cond == if (w_walk->waitp->cond ==
nullptr || // no condition => vacuously true OR nullptr || // no condition => vacuously true OR
// this thread's condition is true (w_walk->waitp->cond != known_false &&
EvalConditionIgnored(this, w_walk->waitp->cond)) { // this thread's condition is not known false, AND
// is in fact true
EvalConditionIgnored(this, w_walk->waitp->cond))) {
if (w == nullptr) { if (w == nullptr) {
w_walk->wake = true; // can wake this waiter w_walk->wake = true; // can wake this waiter
w = w_walk; w = w_walk;
...@@ -2220,6 +2228,8 @@ ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams* waitp) { ...@@ -2220,6 +2228,8 @@ ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams* waitp) {
} else { // writer with true condition } else { // writer with true condition
wr_wait = kMuWrWait; wr_wait = kMuWrWait;
} }
} else { // can't wake; condition false
known_false = w_walk->waitp->cond; // remember last false condition
} }
if (w_walk->wake) { // we're waking reader w_walk if (w_walk->wake) { // we're waking reader w_walk
pw_walk = w_walk; // don't skip similar waiters pw_walk = w_walk; // don't skip similar waiters
...@@ -2712,11 +2722,17 @@ Condition::Condition(const bool* cond) ...@@ -2712,11 +2722,17 @@ Condition::Condition(const bool* cond)
StoreCallback(dereference); StoreCallback(dereference);
} }
bool Condition::Eval() const { return (*this->eval_)(this); } bool Condition::Eval() const {
// eval_ == null for kTrue
return (this->eval_ == nullptr) || (*this->eval_)(this);
}
bool Condition::GuaranteedEqual(const Condition* a, const Condition* b) { bool Condition::GuaranteedEqual(const Condition* a, const Condition* b) {
if (a == nullptr || b == nullptr) { // kTrue logic.
return a == b; if (a == nullptr || a->eval_ == nullptr) {
return b == nullptr || b->eval_ == nullptr;
} else if (b == nullptr || b->eval_ == nullptr) {
return false;
} }
// Check equality of the representative fields. // Check equality of the representative fields.
return a->eval_ == b->eval_ && a->arg_ == b->arg_ && return a->eval_ == b->eval_ && a->arg_ == b->arg_ &&
......
...@@ -833,10 +833,10 @@ class Condition { ...@@ -833,10 +833,10 @@ class Condition {
#endif #endif
// Function with which to evaluate callbacks and/or arguments. // Function with which to evaluate callbacks and/or arguments.
bool (*const eval_)(const Condition*); bool (*eval_)(const Condition*) = nullptr;
// Either an argument for a function call or an object for a method call. // Either an argument for a function call or an object for a method call.
void* const arg_; void* arg_ = nullptr;
// Various functions eval_ can point to: // Various functions eval_ can point to:
static bool CallVoidPtrFunction(const Condition*); static bool CallVoidPtrFunction(const Condition*);
...@@ -859,10 +859,8 @@ class Condition { ...@@ -859,10 +859,8 @@ class Condition {
std::memcpy(callback, callback_, sizeof(*callback)); std::memcpy(callback, callback_, sizeof(*callback));
} }
static bool AlwaysTrue(const Condition*) { return true; }
// Used only to create kTrue. // Used only to create kTrue.
constexpr Condition() : eval_(AlwaysTrue), arg_(nullptr) {} constexpr Condition() = default;
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment