summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--absl/synchronization/mutex.cc111
-rw-r--r--absl/synchronization/mutex.h56
2 files changed, 56 insertions, 111 deletions
diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc
index dc34d8a9..d63ec5ec 100644
--- a/absl/synchronization/mutex.cc
+++ b/absl/synchronization/mutex.cc
@@ -1522,104 +1522,25 @@ void Mutex::ReaderLock() {
ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_read_lock, 0);
}
-void Mutex::LockWhen(const Condition& cond) {
- ABSL_TSAN_MUTEX_PRE_LOCK(this, 0);
- GraphId id = DebugOnlyDeadlockCheck(this);
- this->LockSlow(kExclusive, &cond, 0);
- DebugOnlyLockEnter(this, id);
- ABSL_TSAN_MUTEX_POST_LOCK(this, 0, 0);
-}
-
-bool Mutex::LockWhenWithTimeout(const Condition& cond, absl::Duration timeout) {
- ABSL_TSAN_MUTEX_PRE_LOCK(this, 0);
- GraphId id = DebugOnlyDeadlockCheck(this);
- bool res = LockSlowWithDeadline(kExclusive, &cond, KernelTimeout(timeout), 0);
- DebugOnlyLockEnter(this, id);
- ABSL_TSAN_MUTEX_POST_LOCK(this, 0, 0);
- return res;
-}
-
-bool Mutex::LockWhenWithDeadline(const Condition& cond, absl::Time deadline) {
- ABSL_TSAN_MUTEX_PRE_LOCK(this, 0);
- GraphId id = DebugOnlyDeadlockCheck(this);
- bool res =
- LockSlowWithDeadline(kExclusive, &cond, KernelTimeout(deadline), 0);
- DebugOnlyLockEnter(this, id);
- ABSL_TSAN_MUTEX_POST_LOCK(this, 0, 0);
- return res;
-}
-
-void Mutex::ReaderLockWhen(const Condition& cond) {
- ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_read_lock);
- GraphId id = DebugOnlyDeadlockCheck(this);
- this->LockSlow(kShared, &cond, 0);
- DebugOnlyLockEnter(this, id);
- ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_read_lock, 0);
-}
-
-bool Mutex::ReaderLockWhenWithTimeout(const Condition& cond,
- absl::Duration timeout) {
- ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_read_lock);
- GraphId id = DebugOnlyDeadlockCheck(this);
- bool res = LockSlowWithDeadline(kShared, &cond, KernelTimeout(timeout), 0);
- DebugOnlyLockEnter(this, id);
- ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_read_lock, 0);
- return res;
-}
-
-bool Mutex::ReaderLockWhenWithDeadline(const Condition& cond,
- absl::Time deadline) {
- ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_read_lock);
+bool Mutex::LockWhenCommon(const Condition& cond,
+ synchronization_internal::KernelTimeout t,
+ bool write) {
+ MuHow how = write ? kExclusive : kShared;
+ ABSL_TSAN_MUTEX_PRE_LOCK(this, TsanFlags(how));
GraphId id = DebugOnlyDeadlockCheck(this);
- bool res = LockSlowWithDeadline(kShared, &cond, KernelTimeout(deadline), 0);
+ bool res = LockSlowWithDeadline(how, &cond, t, 0);
DebugOnlyLockEnter(this, id);
- ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_read_lock, 0);
+ ABSL_TSAN_MUTEX_POST_LOCK(this, TsanFlags(how), 0);
return res;
}
-void Mutex::Await(const Condition& cond) {
- if (cond.Eval()) { // condition already true; nothing to do
- if (kDebugMode) {
- this->AssertReaderHeld();
- }
- } else { // normal case
- ABSL_RAW_CHECK(this->AwaitCommon(cond, KernelTimeout::Never()),
- "condition untrue on return from Await");
- }
-}
-
-bool Mutex::AwaitWithTimeout(const Condition& cond, absl::Duration timeout) {
- if (cond.Eval()) { // condition already true; nothing to do
- if (kDebugMode) {
- this->AssertReaderHeld();
- }
- return true;
+bool Mutex::AwaitCommon(const Condition& cond, KernelTimeout t) {
+ if (kDebugMode) {
+ this->AssertReaderHeld();
}
-
- KernelTimeout t{timeout};
- bool res = this->AwaitCommon(cond, t);
- ABSL_RAW_CHECK(res || t.has_timeout(),
- "condition untrue on return from Await");
- return res;
-}
-
-bool Mutex::AwaitWithDeadline(const Condition& cond, absl::Time deadline) {
if (cond.Eval()) { // condition already true; nothing to do
- if (kDebugMode) {
- this->AssertReaderHeld();
- }
return true;
}
-
- KernelTimeout t{deadline};
- bool res = this->AwaitCommon(cond, t);
- ABSL_RAW_CHECK(res || t.has_timeout(),
- "condition untrue on return from Await");
- return res;
-}
-
-bool Mutex::AwaitCommon(const Condition& cond, KernelTimeout t) {
- this->AssertReaderHeld();
MuHow how =
(mu_.load(std::memory_order_relaxed) & kMuWriter) ? kExclusive : kShared;
ABSL_TSAN_MUTEX_PRE_UNLOCK(this, TsanFlags(how));
@@ -1634,6 +1555,8 @@ bool Mutex::AwaitCommon(const Condition& cond, KernelTimeout t) {
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);
+ ABSL_RAW_CHECK(res || t.has_timeout(),
+ "condition untrue on return from Await");
return res;
}
@@ -2654,16 +2577,6 @@ bool CondVar::WaitCommon(Mutex* mutex, KernelTimeout t) {
return rc;
}
-bool CondVar::WaitWithTimeout(Mutex* mu, absl::Duration timeout) {
- return WaitCommon(mu, KernelTimeout(timeout));
-}
-
-bool CondVar::WaitWithDeadline(Mutex* mu, absl::Time deadline) {
- return WaitCommon(mu, KernelTimeout(deadline));
-}
-
-void CondVar::Wait(Mutex* mu) { WaitCommon(mu, KernelTimeout::Never()); }
-
// 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
diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h
index f2bafa97..6459053b 100644
--- a/absl/synchronization/mutex.h
+++ b/absl/synchronization/mutex.h
@@ -324,7 +324,9 @@ class ABSL_LOCKABLE Mutex {
// `true`, `Await()` *may* skip the release/re-acquire step.
//
// `Await()` requires that this thread holds this `Mutex` in some mode.
- void Await(const Condition& cond);
+ void Await(const Condition& cond) {
+ AwaitCommon(cond, synchronization_internal::KernelTimeout::Never());
+ }
// Mutex::LockWhen()
// Mutex::ReaderLockWhen()
@@ -334,9 +336,15 @@ class ABSL_LOCKABLE Mutex {
// be acquired, then atomically acquires this `Mutex`. `LockWhen()` is
// logically equivalent to `*Lock(); Await();` though they may have different
// performance characteristics.
- void LockWhen(const Condition& cond) ABSL_EXCLUSIVE_LOCK_FUNCTION();
+ void LockWhen(const Condition& cond) ABSL_EXCLUSIVE_LOCK_FUNCTION() {
+ LockWhenCommon(cond, synchronization_internal::KernelTimeout::Never(),
+ true);
+ }
- void ReaderLockWhen(const Condition& cond) ABSL_SHARED_LOCK_FUNCTION();
+ void ReaderLockWhen(const Condition& cond) ABSL_SHARED_LOCK_FUNCTION() {
+ LockWhenCommon(cond, synchronization_internal::KernelTimeout::Never(),
+ false);
+ }
void WriterLockWhen(const Condition& cond) ABSL_EXCLUSIVE_LOCK_FUNCTION() {
this->LockWhen(cond);
@@ -363,9 +371,13 @@ class ABSL_LOCKABLE Mutex {
// Negative timeouts are equivalent to a zero timeout.
//
// This method requires that this thread holds this `Mutex` in some mode.
- bool AwaitWithTimeout(const Condition& cond, absl::Duration timeout);
+ bool AwaitWithTimeout(const Condition& cond, absl::Duration timeout) {
+ return AwaitCommon(cond, synchronization_internal::KernelTimeout{timeout});
+ }
- bool AwaitWithDeadline(const Condition& cond, absl::Time deadline);
+ bool AwaitWithDeadline(const Condition& cond, absl::Time deadline) {
+ return AwaitCommon(cond, synchronization_internal::KernelTimeout{deadline});
+ }
// Mutex::LockWhenWithTimeout()
// Mutex::ReaderLockWhenWithTimeout()
@@ -379,9 +391,15 @@ class ABSL_LOCKABLE Mutex {
//
// Negative timeouts are equivalent to a zero timeout.
bool LockWhenWithTimeout(const Condition& cond, absl::Duration timeout)
- ABSL_EXCLUSIVE_LOCK_FUNCTION();
+ ABSL_EXCLUSIVE_LOCK_FUNCTION() {
+ return LockWhenCommon(
+ cond, synchronization_internal::KernelTimeout{timeout}, true);
+ }
bool ReaderLockWhenWithTimeout(const Condition& cond, absl::Duration timeout)
- ABSL_SHARED_LOCK_FUNCTION();
+ ABSL_SHARED_LOCK_FUNCTION() {
+ return LockWhenCommon(
+ cond, synchronization_internal::KernelTimeout{timeout}, false);
+ }
bool WriterLockWhenWithTimeout(const Condition& cond, absl::Duration timeout)
ABSL_EXCLUSIVE_LOCK_FUNCTION() {
return this->LockWhenWithTimeout(cond, timeout);
@@ -399,9 +417,15 @@ class ABSL_LOCKABLE Mutex {
//
// Deadlines in the past are equivalent to an immediate deadline.
bool LockWhenWithDeadline(const Condition& cond, absl::Time deadline)
- ABSL_EXCLUSIVE_LOCK_FUNCTION();
+ ABSL_EXCLUSIVE_LOCK_FUNCTION() {
+ return LockWhenCommon(
+ cond, synchronization_internal::KernelTimeout{deadline}, true);
+ }
bool ReaderLockWhenWithDeadline(const Condition& cond, absl::Time deadline)
- ABSL_SHARED_LOCK_FUNCTION();
+ ABSL_SHARED_LOCK_FUNCTION() {
+ return LockWhenCommon(
+ cond, synchronization_internal::KernelTimeout{deadline}, false);
+ }
bool WriterLockWhenWithDeadline(const Condition& cond, absl::Time deadline)
ABSL_EXCLUSIVE_LOCK_FUNCTION() {
return this->LockWhenWithDeadline(cond, deadline);
@@ -500,6 +524,8 @@ class ABSL_LOCKABLE Mutex {
// Common code between Await() and AwaitWithTimeout/Deadline()
bool AwaitCommon(const Condition& cond,
synchronization_internal::KernelTimeout t);
+ bool LockWhenCommon(const Condition& cond,
+ synchronization_internal::KernelTimeout t, bool write);
// Attempt to remove thread s from queue.
void TryRemove(base_internal::PerThreadSynch* s);
// Block a thread on mutex.
@@ -888,7 +914,9 @@ class CondVar {
// spurious wakeup), then reacquires the `Mutex` and returns.
//
// Requires and ensures that the current thread holds the `Mutex`.
- void Wait(Mutex* mu);
+ void Wait(Mutex* mu) {
+ WaitCommon(mu, synchronization_internal::KernelTimeout::Never());
+ }
// CondVar::WaitWithTimeout()
//
@@ -903,7 +931,9 @@ class CondVar {
// to return `true` or `false`.
//
// Requires and ensures that the current thread holds the `Mutex`.
- bool WaitWithTimeout(Mutex* mu, absl::Duration timeout);
+ bool WaitWithTimeout(Mutex* mu, absl::Duration timeout) {
+ return WaitCommon(mu, synchronization_internal::KernelTimeout(timeout));
+ }
// CondVar::WaitWithDeadline()
//
@@ -920,7 +950,9 @@ class CondVar {
// to return `true` or `false`.
//
// Requires and ensures that the current thread holds the `Mutex`.
- bool WaitWithDeadline(Mutex* mu, absl::Time deadline);
+ bool WaitWithDeadline(Mutex* mu, absl::Time deadline) {
+ return WaitCommon(mu, synchronization_internal::KernelTimeout(deadline));
+ }
// CondVar::Signal()
//