Skip to content

Commit

Permalink
Merge pull request #292 from thomcc/word_lock_ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
Amanieu committed Aug 9, 2021
2 parents 26c41e4 + 4fd88be commit 6bbf522
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
10 changes: 10 additions & 0 deletions core/build.rs
@@ -0,0 +1,10 @@
// Automatically detect tsan in a way that's compatible with both stable (which
// doesn't support sanitizers) and nightly (which does). Works because build
// scripts gets `cfg` info, even if the cfg is unstable.
fn main() {
println!("cargo:rerun-if-changed=build.rs");
let santizer_list = std::env::var("CARGO_CFG_SANITIZE").unwrap_or_default();
if santizer_list.contains("thread") {
println!("cargo:rustc-cfg=tsan_enabled");
}
}
17 changes: 14 additions & 3 deletions core/src/word_lock.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -238,7 +238,7 @@ impl WordLock {
}

// Need an acquire fence before reading the new queue
fence(Ordering::Acquire);
fence_acquire(&self.state);
continue;
}

Expand All @@ -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;
}
}
Expand All @@ -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;
Expand Down

0 comments on commit 6bbf522

Please sign in to comment.