about summary refs log tree commit diff
path: root/src/libcore/sync
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-04-08 22:37:35 +0000
committerbors <bors@rust-lang.org>2017-04-08 22:37:35 +0000
commitb2d9b6323e3573839760ea3dc83a2c1658a01cf2 (patch)
tree3a74650bca3c60638f33c9b64a665b829f1a7de0 /src/libcore/sync
parent666e7148d167de551a7c3692caf9966f49773f4c (diff)
parentf093d59c31bd2064328e24d0ec76e0d105fc32fc (diff)
downloadrust-b2d9b6323e3573839760ea3dc83a2c1658a01cf2.tar.gz
rust-b2d9b6323e3573839760ea3dc83a2c1658a01cf2.zip
Auto merge of #41092 - jonhoo:std-fence-intrinsics, r=alexcrichton
Add safe wrapper for atomic_compilerfence intrinsics

This PR adds a proposed safe wrapper for the `atomic_singlethreadfence_*` intrinsics introduced by [RFC #888](https://github.com/rust-lang/rfcs/pull/888). See #41091 for further discussion.
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 a4050f271eb..0c70524ead2 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -1591,6 +1591,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 = "compiler_barriers", 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 {