about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-07-28 03:55:22 -0700
committerbors <bors@rust-lang.org>2013-07-28 03:55:22 -0700
commit5842ab36b81f0a3e8d6dd48a200bc405ad19ca96 (patch)
tree3e5d310206b16cf3048abe6d16ea27d360636b7a /src/libstd
parentfe9929e303f4e0322fd0f38ec6cb6b3ec932e4a3 (diff)
parent639819f3d991a63883bc571f9aed13b8e59036d6 (diff)
downloadrust-5842ab36b81f0a3e8d6dd48a200bc405ad19ca96.tar.gz
rust-5842ab36b81f0a3e8d6dd48a200bc405ad19ca96.zip
auto merge of #8087 : Aatch/rust/atomics, r=huonw
Adds a fence operation to close #8061

Also adds static initializers to for atomic types. Since the fields are private, you aren't able to have `static mut` variables that are an atomic type. Each atomic type's initializer starts at a 0-value (so unset for `AtomicFlag` and false for `AtomicBool`).
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/unstable/atomics.rs48
-rw-r--r--src/libstd/unstable/intrinsics.rs9
2 files changed, 57 insertions, 0 deletions
diff --git a/src/libstd/unstable/atomics.rs b/src/libstd/unstable/atomics.rs
index 712c32d2436..6f514ca609d 100644
--- a/src/libstd/unstable/atomics.rs
+++ b/src/libstd/unstable/atomics.rs
@@ -75,6 +75,10 @@ pub enum Ordering {
     SeqCst
 }
 
+pub static INIT_ATOMIC_FLAG : AtomicFlag = AtomicFlag { v: 0 };
+pub static INIT_ATOMIC_BOOL : AtomicBool = AtomicBool { v: 0 };
+pub static INIT_ATOMIC_INT  : AtomicInt  = AtomicInt  { v: 0 };
+pub static INIT_ATOMIC_UINT : AtomicUint = AtomicUint { v: 0 };
 
 impl AtomicFlag {
 
@@ -569,6 +573,35 @@ pub unsafe fn atomic_umin<T>(dst: &mut T, val: T, order: Ordering) -> T {
     })
 }
 
+/**
+ * An atomic fence.
+ *
+ * A fence 'A' which has `Release` ordering semantics, synchronizes with a
+ * fence 'B' with (at least) `Acquire` semantics, if and only if there exists
+ * atomic operations X and Y, both operating on some atomic object 'M' such
+ * that A is sequenced before X, Y is synchronized before B and Y obsevers
+ * the change to M. This provides a happens-before dependence between A and B.
+ *
+ * Atomic operations with `Release` or `Acquire` semantics can also synchronize
+ * with a fence.
+ *
+ * A fence with has `SeqCst` ordering, in addition to having both `Acquire` and
+ * `Release` semantics, participates in the global program order of the other
+ * `SeqCst` operations and/or fences.
+ *
+ * Accepts `Acquire`, `Release`, `AcqRel` and `SeqCst` orderings.
+ */
+#[inline] #[cfg(not(stage0))]
+pub fn fence(order: Ordering) {
+    unsafe {
+        match order {
+            Acquire => intrinsics::atomic_fence_acq(),
+            Release => intrinsics::atomic_fence_rel(),
+            AcqRel  => intrinsics::atomic_fence_rel(),
+            _       => intrinsics::atomic_fence(),
+        }
+    }
+}
 
 #[cfg(test)]
 mod test {
@@ -630,4 +663,19 @@ mod test {
         assert_eq!(a.fetch_and(false, SeqCst),true);
         assert_eq!(a.load(SeqCst),false);
     }
+
+    static mut S_FLAG : AtomicFlag = INIT_ATOMIC_FLAG;
+    static mut S_BOOL : AtomicBool = INIT_ATOMIC_BOOL;
+    static mut S_INT  : AtomicInt  = INIT_ATOMIC_INT;
+    static mut S_UINT : AtomicUint = INIT_ATOMIC_UINT;
+
+    #[test]
+    fn static_init() {
+        unsafe {
+            assert!(!S_FLAG.test_and_set(SeqCst));
+            assert!(!S_BOOL.load(SeqCst));
+            assert!(S_INT.load(SeqCst) == 0);
+            assert!(S_UINT.load(SeqCst) == 0);
+        }
+    }
 }
diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs
index 76958fa333f..655ede6b4eb 100644
--- a/src/libstd/unstable/intrinsics.rs
+++ b/src/libstd/unstable/intrinsics.rs
@@ -256,6 +256,15 @@ extern "rust-intrinsic" {
     pub fn atomic_umax_acqrel(dst: &mut int, src: int) -> int;
     pub fn atomic_umax_relaxed(dst: &mut int, src: int) -> int;
 
+    #[cfg(not(stage0))]
+    pub fn atomic_fence();
+    #[cfg(not(stage0))]
+    pub fn atomic_fence_acq();
+    #[cfg(not(stage0))]
+    pub fn atomic_fence_rel();
+    #[cfg(not(stage0))]
+    pub fn atomic_fence_acqrel();
+
     /// The size of a type in bytes.
     ///
     /// This is the exact number of bytes in memory taken up by a