diff options
| author | bors <bors@rust-lang.org> | 2013-07-28 03:55:22 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-07-28 03:55:22 -0700 |
| commit | 5842ab36b81f0a3e8d6dd48a200bc405ad19ca96 (patch) | |
| tree | 3e5d310206b16cf3048abe6d16ea27d360636b7a /src/libstd | |
| parent | fe9929e303f4e0322fd0f38ec6cb6b3ec932e4a3 (diff) | |
| parent | 639819f3d991a63883bc571f9aed13b8e59036d6 (diff) | |
| download | rust-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.rs | 48 | ||||
| -rw-r--r-- | src/libstd/unstable/intrinsics.rs | 9 |
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 |
