about summary refs log tree commit diff
path: root/src/libcore/sync
diff options
context:
space:
mode:
authorJon Gjengset <jon@thesquareplanet.com>2017-04-05 15:33:24 -0400
committerJon Gjengset <jon@thesquareplanet.com>2017-04-05 15:46:55 -0400
commit2598e4574e9136690add3cef55fbb8ac7356f3d2 (patch)
treeb8271dbef34aee84df8fca24eb1b881735dfdecb /src/libcore/sync
parentad5dfecc6ae23bb7d2b8075d705011918ab4f399 (diff)
downloadrust-2598e4574e9136690add3cef55fbb8ac7356f3d2.tar.gz
rust-2598e4574e9136690add3cef55fbb8ac7356f3d2.zip
Add safe wrapper for atomic_singlethreadfence_*
Diffstat (limited to 'src/libcore/sync')
-rw-r--r--src/libcore/sync/atomic.rs41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index ae47e6fdfa9..948edda832b 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -1572,6 +1572,47 @@ pub fn fence(order: Ordering) {
 }
 
 
+/// A compiler memory barrier.
+///
+/// `compiler_barrier` does not emit any machine code, but prevents the compiler from re-ordering
+/// memory operations across this point. Which reorderings are disallowed is dictated by the given
+/// [`Ordering`]. Note that `compiler_barrier` does *not* introduce inter-thread memory
+/// synchronization; for that, a [`fence`] is needed.
+///
+/// The re-ordering prevented by the different ordering semantics are:
+///
+///  - with [`SeqCst`], no re-ordering of reads and writes across this point is allowed.
+///  - with [`Release`], preceding reads and writes cannot be moved past subsequent writes.
+///  - with [`Acquire`], subsequent reads and writes cannot be moved ahead of preceding reads.
+///  - with [`AcqRel`], both of the above rules are enforced.
+///
+/// # Panics
+///
+/// Panics if `order` is [`Relaxed`].
+///
+/// [`fence`]: fn.fence.html
+/// [`Ordering`]: enum.Ordering.html
+/// [`Acquire`]: enum.Ordering.html#variant.Acquire
+/// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
+/// [`Release`]: enum.Ordering.html#variant.Release
+/// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
+/// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
+#[inline]
+#[unstable(feature = "std_compiler_fences", issue = "41091")]
+pub fn compiler_barrier(order: Ordering) {
+    unsafe {
+        match order {
+            Acquire => intrinsics::atomic_singlethreadfence_acq(),
+            Release => intrinsics::atomic_singlethreadfence_rel(),
+            AcqRel => intrinsics::atomic_singlethreadfence_acqrel(),
+            SeqCst => intrinsics::atomic_singlethreadfence(),
+            Relaxed => panic!("there is no such thing as a relaxed barrier"),
+            __Nonexhaustive => panic!("invalid memory ordering"),
+        }
+    }
+}
+
+
 #[cfg(target_has_atomic = "8")]
 #[stable(feature = "atomic_debug", since = "1.3.0")]
 impl fmt::Debug for AtomicBool {