about summary refs log tree commit diff
path: root/src/liballoc/sync.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-03-21 04:34:04 +0000
committerbors <bors@rust-lang.org>2020-03-21 04:34:04 +0000
commit5f13820478907b09d50baf74f3ff2b78499ecd6c (patch)
treef8a09a299d9c7e09f562913e7aadefd3c4f12f0e /src/liballoc/sync.rs
parent1057dc97afce39ff6a224966ece3ed438af4c1f5 (diff)
parent54285db640453d2beec91423cb8cc792f52797f2 (diff)
downloadrust-5f13820478907b09d50baf74f3ff2b78499ecd6c.tar.gz
rust-5f13820478907b09d50baf74f3ff2b78499ecd6c.zip
Auto merge of #70205 - Centril:rollup-0jq9k4s, r=Centril
Rollup of 16 pull requests

Successful merges:

 - #65097 (Make std::sync::Arc compatible with ThreadSanitizer)
 - #69033 (Use generator resume arguments in the async/await lowering)
 - #69997 (add `Option::{zip,zip_with}` methods under "option_zip" gate)
 - #70038 (Remove the call that makes miri fail)
 - #70058 (can_begin_literal_maybe_minus: `true` on `"-"? lit` NTs.)
 - #70111 (BTreeMap: remove shared root)
 - #70139 (add delay_span_bug to TransmuteSizeDiff, just to be sure)
 - #70165 (Remove the erase regions MIR transform)
 - #70166 (Derive PartialEq, Eq and Hash for RangeInclusive)
 - #70176 (Add tests for #58319 and #65131)
 - #70177 (Fix oudated comment for NamedRegionMap)
 - #70184 (expand_include: set `.directory` to dir of included file.)
 - #70187 (more clippy fixes)
 - #70188 (Clean up E0439 explanation)
 - #70189 (Abi::is_signed: assert that we are a Scalar)
 - #70194 (#[must_use] on split_off())

Failed merges:

r? @ghost
Diffstat (limited to 'src/liballoc/sync.rs')
-rw-r--r--src/liballoc/sync.rs25
1 files changed, 21 insertions, 4 deletions
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 4a0cf2984ed..d9b54fb0b17 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -40,6 +40,23 @@ mod tests;
 /// necessarily) at _exactly_ `MAX_REFCOUNT + 1` references.
 const MAX_REFCOUNT: usize = (isize::MAX) as usize;
 
+#[cfg(not(sanitize = "thread"))]
+macro_rules! acquire {
+    ($x:expr) => {
+        atomic::fence(Acquire)
+    };
+}
+
+// ThreadSanitizer does not support memory fences. To avoid false positive
+// reports in Arc / Weak implementation use atomic loads for synchronization
+// instead.
+#[cfg(sanitize = "thread")]
+macro_rules! acquire {
+    ($x:expr) => {
+        $x.load(Acquire)
+    };
+}
+
 /// A thread-safe reference-counting pointer. 'Arc' stands for 'Atomically
 /// Reference Counted'.
 ///
@@ -402,7 +419,7 @@ impl<T> Arc<T> {
             return Err(this);
         }
 
-        atomic::fence(Acquire);
+        acquire!(this.inner().strong);
 
         unsafe {
             let elem = ptr::read(&this.ptr.as_ref().data);
@@ -739,7 +756,7 @@ impl<T: ?Sized> Arc<T> {
         ptr::drop_in_place(&mut self.ptr.as_mut().data);
 
         if self.inner().weak.fetch_sub(1, Release) == 1 {
-            atomic::fence(Acquire);
+            acquire!(self.inner().weak);
             Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()))
         }
     }
@@ -1243,7 +1260,7 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Arc<T> {
         //
         // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
         // [2]: (https://github.com/rust-lang/rust/pull/41714)
-        atomic::fence(Acquire);
+        acquire!(self.inner().strong);
 
         unsafe {
             self.drop_slow();
@@ -1701,7 +1718,7 @@ impl<T: ?Sized> Drop for Weak<T> {
         let inner = if let Some(inner) = self.inner() { inner } else { return };
 
         if inner.weak.fetch_sub(1, Release) == 1 {
-            atomic::fence(Acquire);
+            acquire!(inner.weak);
             unsafe { Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref())) }
         }
     }