aboutsummaryrefslogtreecommitdiff
path: root/absl/synchronization/mutex.cc
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2023-12-19 07:10:16 -0800
committerCopybara-Service <copybara-worker@google.com>2023-12-19 07:11:23 -0800
commite54fb4e1440c3c1d6933ceec2b36012228507719 (patch)
treea133a587cc0b9443c4e143d776710a93030d7f39 /absl/synchronization/mutex.cc
parentbae260199fffe782d5a5414bb80cfe49abb1436f (diff)
downloadabseil-e54fb4e1440c3c1d6933ceec2b36012228507719.tar.gz
abseil-e54fb4e1440c3c1d6933ceec2b36012228507719.tar.bz2
abseil-e54fb4e1440c3c1d6933ceec2b36012228507719.zip
Mutex: Prevent false race in EnableInvariantDebugging.
The added test exposes a false TSan race report in EnableInvariantDebugging/EnableDebugLog related to SynchEvent reuse. We ignore most of the stuff that happens inside of the Mutex code, but not for the code inside of EnableInvariantDebugging/EnableDebugLog. So these can cause occasional false reports on SynchEvent bankruptcy. Also ignore accesses in EnableInvariantDebugging/EnableDebugLog. PiperOrigin-RevId: 592226791 Change-Id: I066edb1ef5661ba6cf86a195f91a9d5328b93d10
Diffstat (limited to 'absl/synchronization/mutex.cc')
-rw-r--r--absl/synchronization/mutex.cc10
1 files changed, 10 insertions, 0 deletions
diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc
index cb751927..98574c0b 100644
--- a/absl/synchronization/mutex.cc
+++ b/absl/synchronization/mutex.cc
@@ -748,6 +748,13 @@ void Mutex::Dtor() {
#endif
void Mutex::EnableDebugLog(const char* name) {
+ // Need to disable writes here and in EnableInvariantDebugging to prevent
+ // false race reports on SynchEvent objects. TSan ignores synchronization
+ // on synch_event_mu in Lock/Unlock/etc methods due to mutex annotations,
+ // but it sees few accesses to SynchEvent in EvalConditionAnnotated.
+ // If we don't ignore accesses here, it can result in false races
+ // between EvalConditionAnnotated and SynchEvent reuse in EnsureSynchEvent.
+ ABSL_ANNOTATE_IGNORE_WRITES_BEGIN();
SynchEvent* e = EnsureSynchEvent(&this->mu_, name, kMuEvent, kMuSpin);
e->log = true;
UnrefSynchEvent(e);
@@ -760,6 +767,7 @@ void Mutex::EnableDebugLog(const char* name) {
// actual destructor code into the separate Dtor function and force the
// compiler to emit this function even if it's inline by taking its address.
ABSL_ATTRIBUTE_UNUSED volatile auto dtor = &Mutex::Dtor;
+ ABSL_ANNOTATE_IGNORE_WRITES_END();
}
void EnableMutexInvariantDebugging(bool enabled) {
@@ -767,6 +775,7 @@ void EnableMutexInvariantDebugging(bool enabled) {
}
void Mutex::EnableInvariantDebugging(void (*invariant)(void*), void* arg) {
+ ABSL_ANNOTATE_IGNORE_WRITES_BEGIN();
if (synch_check_invariants.load(std::memory_order_acquire) &&
invariant != nullptr) {
SynchEvent* e = EnsureSynchEvent(&this->mu_, nullptr, kMuEvent, kMuSpin);
@@ -774,6 +783,7 @@ void Mutex::EnableInvariantDebugging(void (*invariant)(void*), void* arg) {
e->arg = arg;
UnrefSynchEvent(e);
}
+ ABSL_ANNOTATE_IGNORE_WRITES_END();
}
void SetMutexDeadlockDetectionMode(OnDeadlockCycle mode) {