summaryrefslogtreecommitdiff
path: root/src/word_lock.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/word_lock.rs')
-rw-r--r--src/word_lock.rs17
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;