diff options
Diffstat (limited to 'src/word_lock.rs')
-rw-r--r-- | src/word_lock.rs | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/src/word_lock.rs b/src/word_lock.rs index 450e985..1109401 100644 --- a/src/word_lock.rs +++ b/src/word_lock.rs @@ -154,7 +154,7 @@ impl WordLock { if let Err(x) = self.state.compare_exchange_weak( state, state.with_queue_head(thread_data), - Ordering::Release, + Ordering::AcqRel, Ordering::Relaxed, ) { return x; @@ -238,7 +238,7 @@ impl WordLock { } // Need an acquire fence before reading the new queue - fence(Ordering::Acquire); + fence_acquire(&self.state); continue; } @@ -263,7 +263,7 @@ impl WordLock { continue; } else { // Need an acquire fence before reading the new queue - fence(Ordering::Acquire); + fence_acquire(&self.state); continue 'outer; } } @@ -286,6 +286,17 @@ impl WordLock { } } +// Thread-Sanitizer only has partial fence support, so when running under it, we +// try and avoid false positives by using a discarded acquire load instead. +#[inline] +fn fence_acquire(a: &AtomicUsize) { + if cfg!(tsan_enabled) { + let _ = a.load(Ordering::Acquire); + } else { + fence(Ordering::Acquire); + } +} + trait LockState { fn is_locked(self) -> bool; fn is_queue_locked(self) -> bool; |