about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-07-26 08:02:06 -0700
committerbors <bors@rust-lang.org>2013-07-26 08:02:06 -0700
commit15ab6fde7f37155385b4072f64e89d722b970fd3 (patch)
treec197c9c5b9eaec9841b048fa382e2908a64c7f63 /src/libstd
parent382b037252c213150f2a298524db2c7674804126 (diff)
parent7cc8f4bae0ed20aad04e03e5f3812fb7b8288f78 (diff)
downloadrust-15ab6fde7f37155385b4072f64e89d722b970fd3.tar.gz
rust-15ab6fde7f37155385b4072f64e89d722b970fd3.zip
auto merge of #8039 : Xazax-hun/rust/master, r=brson
Added some more atomic operations. https://github.com/mozilla/rust/issues/7421
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/unstable/atomics.rs186
1 files changed, 184 insertions, 2 deletions
diff --git a/src/libstd/unstable/atomics.rs b/src/libstd/unstable/atomics.rs
index b595d3e1a80..712c32d2436 100644
--- a/src/libstd/unstable/atomics.rs
+++ b/src/libstd/unstable/atomics.rs
@@ -96,7 +96,7 @@ impl AtomicFlag {
      */
     #[inline]
     pub fn test_and_set(&mut self, order: Ordering) -> bool {
-        unsafe {atomic_compare_and_swap(&mut self.v, 0, 1, order) > 0}
+        unsafe { atomic_compare_and_swap(&mut self.v, 0, 1, order) > 0 }
     }
 }
 
@@ -121,7 +121,7 @@ impl AtomicBool {
     pub fn swap(&mut self, val: bool, order: Ordering) -> bool {
         let val = if val { 1 } else { 0 };
 
-        unsafe { atomic_swap(&mut self.v, val, order) > 0}
+        unsafe { atomic_swap(&mut self.v, val, order) > 0 }
     }
 
     #[inline]
@@ -131,6 +131,38 @@ impl AtomicBool {
 
         unsafe { atomic_compare_and_swap(&mut self.v, old, new, order) > 0 }
     }
+
+    /// Returns the old value
+    #[inline]
+    pub fn fetch_and(&mut self, val: bool, order: Ordering) -> bool {
+        let val = if val { 1 } else { 0 };
+
+        unsafe { atomic_and(&mut self.v, val, order) > 0 }
+    }
+
+    /// Returns the old value
+    #[inline]
+    pub fn fetch_nand(&mut self, val: bool, order: Ordering) -> bool {
+        let val = if val { 1 } else { 0 };
+
+        unsafe { atomic_nand(&mut self.v, val, order) > 0 }
+    }
+
+    /// Returns the old value
+    #[inline]
+    pub fn fetch_or(&mut self, val: bool, order: Ordering) -> bool {
+        let val = if val { 1 } else { 0 };
+
+        unsafe { atomic_or(&mut self.v, val, order) > 0 }
+    }
+
+    /// Returns the old value
+    #[inline]
+    pub fn fetch_xor(&mut self, val: bool, order: Ordering) -> bool {
+        let val = if val { 1 } else { 0 };
+
+        unsafe { atomic_xor(&mut self.v, val, order) > 0 }
+    }
 }
 
 impl AtomicInt {
@@ -169,6 +201,18 @@ impl AtomicInt {
     pub fn fetch_sub(&mut self, val: int, order: Ordering) -> int {
         unsafe { atomic_sub(&mut self.v, val, order) }
     }
+
+    /// Returns the old value
+    #[inline]
+    pub fn fetch_min(&mut self, val: int, order: Ordering) -> int {
+        unsafe { atomic_min(&mut self.v, val, order) }
+    }
+
+    /// Returns the old value
+    #[inline]
+    pub fn fetch_max(&mut self, val: int, order: Ordering) -> int {
+        unsafe { atomic_max(&mut self.v, val, order) }
+    }
 }
 
 impl AtomicUint {
@@ -207,6 +251,18 @@ impl AtomicUint {
     pub fn fetch_sub(&mut self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_sub(&mut self.v, val, order) }
     }
+
+    /// Returns the old value
+    #[inline]
+    pub fn fetch_min(&mut self, val: uint, order: Ordering) -> uint {
+        unsafe { atomic_umin(&mut self.v, val, order) }
+    }
+
+    /// Returns the old value
+    #[inline]
+    pub fn fetch_max(&mut self, val: uint, order: Ordering) -> uint {
+        unsafe { atomic_umax(&mut self.v, val, order) }
+    }
 }
 
 impl<T> AtomicPtr<T> {
@@ -395,6 +451,125 @@ pub unsafe fn atomic_compare_and_swap<T>(dst:&mut T, old:T, new:T, order: Orderi
     })
 }
 
+#[inline]
+pub unsafe fn atomic_and<T>(dst: &mut T, val: T, order: Ordering) -> T {
+    let dst = cast::transmute(dst);
+    let val = cast::transmute(val);
+
+    cast::transmute(match order {
+        Acquire => intrinsics::atomic_and_acq(dst, val),
+        Release => intrinsics::atomic_and_rel(dst, val),
+        AcqRel  => intrinsics::atomic_and_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_and_relaxed(dst, val),
+        _       => intrinsics::atomic_and(dst, val)
+    })
+}
+
+
+#[inline]
+pub unsafe fn atomic_nand<T>(dst: &mut T, val: T, order: Ordering) -> T {
+    let dst = cast::transmute(dst);
+    let val = cast::transmute(val);
+
+    cast::transmute(match order {
+        Acquire => intrinsics::atomic_nand_acq(dst, val),
+        Release => intrinsics::atomic_nand_rel(dst, val),
+        AcqRel  => intrinsics::atomic_nand_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_nand_relaxed(dst, val),
+        _       => intrinsics::atomic_nand(dst, val)
+    })
+}
+
+
+#[inline]
+pub unsafe fn atomic_or<T>(dst: &mut T, val: T, order: Ordering) -> T {
+    let dst = cast::transmute(dst);
+    let val = cast::transmute(val);
+
+    cast::transmute(match order {
+        Acquire => intrinsics::atomic_or_acq(dst, val),
+        Release => intrinsics::atomic_or_rel(dst, val),
+        AcqRel  => intrinsics::atomic_or_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_or_relaxed(dst, val),
+        _       => intrinsics::atomic_or(dst, val)
+    })
+}
+
+
+#[inline]
+pub unsafe fn atomic_xor<T>(dst: &mut T, val: T, order: Ordering) -> T {
+    let dst = cast::transmute(dst);
+    let val = cast::transmute(val);
+
+    cast::transmute(match order {
+        Acquire => intrinsics::atomic_xor_acq(dst, val),
+        Release => intrinsics::atomic_xor_rel(dst, val),
+        AcqRel  => intrinsics::atomic_xor_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_xor_relaxed(dst, val),
+        _       => intrinsics::atomic_xor(dst, val)
+    })
+}
+
+
+#[inline]
+pub unsafe fn atomic_max<T>(dst: &mut T, val: T, order: Ordering) -> T {
+    let dst = cast::transmute(dst);
+    let val = cast::transmute(val);
+
+    cast::transmute(match order {
+        Acquire => intrinsics::atomic_max_acq(dst, val),
+        Release => intrinsics::atomic_max_rel(dst, val),
+        AcqRel  => intrinsics::atomic_max_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_max_relaxed(dst, val),
+        _       => intrinsics::atomic_max(dst, val)
+    })
+}
+
+
+#[inline]
+pub unsafe fn atomic_min<T>(dst: &mut T, val: T, order: Ordering) -> T {
+    let dst = cast::transmute(dst);
+    let val = cast::transmute(val);
+
+    cast::transmute(match order {
+        Acquire => intrinsics::atomic_min_acq(dst, val),
+        Release => intrinsics::atomic_min_rel(dst, val),
+        AcqRel  => intrinsics::atomic_min_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_min_relaxed(dst, val),
+        _       => intrinsics::atomic_min(dst, val)
+    })
+}
+
+#[inline]
+pub unsafe fn atomic_umax<T>(dst: &mut T, val: T, order: Ordering) -> T {
+    let dst = cast::transmute(dst);
+    let val = cast::transmute(val);
+
+    cast::transmute(match order {
+        Acquire => intrinsics::atomic_umax_acq(dst, val),
+        Release => intrinsics::atomic_umax_rel(dst, val),
+        AcqRel  => intrinsics::atomic_umax_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_umax_relaxed(dst, val),
+        _       => intrinsics::atomic_umax(dst, val)
+    })
+}
+
+
+#[inline]
+pub unsafe fn atomic_umin<T>(dst: &mut T, val: T, order: Ordering) -> T {
+    let dst = cast::transmute(dst);
+    let val = cast::transmute(val);
+
+    cast::transmute(match order {
+        Acquire => intrinsics::atomic_umin_acq(dst, val),
+        Release => intrinsics::atomic_umin_rel(dst, val),
+        AcqRel  => intrinsics::atomic_umin_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_umin_relaxed(dst, val),
+        _       => intrinsics::atomic_umin(dst, val)
+    })
+}
+
+
 #[cfg(test)]
 mod test {
     use option::*;
@@ -448,4 +623,11 @@ mod test {
         assert!(p.fill(~2, SeqCst).is_none()); // shouldn't fail
         assert_eq!(p.take(SeqCst), Some(~2));
     }
+
+    #[test]
+    fn bool_and() {
+        let mut a = AtomicBool::new(true);
+        assert_eq!(a.fetch_and(false, SeqCst),true);
+        assert_eq!(a.load(SeqCst),false);
+    }
 }