From 8c980b7c9433d19d6d558908718b5f4a83ca87d8 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sat, 17 Jun 2023 22:30:38 +0900 Subject: [PATCH] Make crossbeam-epoch compatible with ThreadSanitizer --- ci/tsan | 3 --- crossbeam-epoch/build.rs | 6 ++++++ crossbeam-epoch/src/internal.rs | 8 +++++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/ci/tsan b/ci/tsan index 9ebb04b4f..67fad001a 100644 --- a/ci/tsan +++ b/ci/tsan @@ -1,8 +1,5 @@ # TSAN suppressions file for crossbeam -# The epoch-based GC uses fences. -race:crossbeam_epoch - # Push and steal operations in crossbeam-deque may cause data races, but such # data races are safe. If a data race happens, the value read by `steal` is # forgotten and the steal operation is then retried. diff --git a/crossbeam-epoch/build.rs b/crossbeam-epoch/build.rs index 86c3b6ff7..a198ec60b 100644 --- a/crossbeam-epoch/build.rs +++ b/crossbeam-epoch/build.rs @@ -54,4 +54,10 @@ fn main() { if !cfg.probe_rustc_version(1, 61) { println!("cargo:rustc-cfg=crossbeam_no_const_fn_trait_bound"); } + + // `cfg(sanitize = "..")` is not stabilized. + let sanitize = env::var("CARGO_CFG_SANITIZE").unwrap_or_default(); + if sanitize.contains("thread") { + println!("cargo:rustc-cfg=crossbeam_sanitize_thread"); + } } diff --git a/crossbeam-epoch/src/internal.rs b/crossbeam-epoch/src/internal.rs index 486993c63..c93d64601 100644 --- a/crossbeam-epoch/src/internal.rs +++ b/crossbeam-epoch/src/internal.rs @@ -250,10 +250,16 @@ impl Global { if local_epoch.is_pinned() && local_epoch.unpinned() != global_epoch { return global_epoch; } + + if cfg!(crossbeam_sanitize_thread) { + local.epoch.load(Ordering::Acquire); + } } } } - atomic::fence(Ordering::Acquire); + if !cfg!(crossbeam_sanitize_thread) { + atomic::fence(Ordering::Acquire); + } // All pinned participants were pinned in the current global epoch. // Now let's advance the global epoch...