#[stable]
pub enum Ordering {
/// No ordering constraints, only atomic operations
+ #[stable]
Relaxed,
/// When coupled with a store, all previous writes become visible
/// to another thread that performs a load with `Acquire` ordering
/// on the same value
+ #[stable]
Release,
/// When coupled with a load, all subsequent loads will see data
/// written before a store with `Release` ordering on the same value
/// in another thread
+ #[stable]
Acquire,
/// When coupled with a load, uses `Acquire` ordering, and with a store
/// `Release` ordering
+ #[stable]
AcqRel,
/// Like `AcqRel` with the additional guarantee that all threads see all
/// sequentially consistent operations in the same order.
+ #[stable]
SeqCst
}
// NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly
const UINT_TRUE: uint = -1;
-#[stable]
impl AtomicBool {
/// Create a new `AtomicBool`
#[inline]
+ #[stable]
pub fn new(v: bool) -> AtomicBool {
let val = if v { UINT_TRUE } else { 0 };
AtomicBool { v: UnsafeCell::new(val), nocopy: marker::NoCopy }
///
/// Fails if `order` is `Release` or `AcqRel`.
#[inline]
+ #[stable]
pub fn load(&self, order: Ordering) -> bool {
unsafe { atomic_load(self.v.get() as *const uint, order) > 0 }
}
///
/// Fails if `order` is `Acquire` or `AcqRel`.
#[inline]
+ #[stable]
pub fn store(&self, val: bool, order: Ordering) {
let val = if val { UINT_TRUE } else { 0 };
/// Store a value, returning the old value
#[inline]
+ #[stable]
pub fn swap(&self, val: bool, order: Ordering) -> bool {
let val = if val { UINT_TRUE } else { 0 };
/// }
/// ```
#[inline]
+ #[stable]
pub fn compare_and_swap(&self, old: bool, new: bool, order: Ordering) -> bool {
let old = if old { UINT_TRUE } else { 0 };
let new = if new { UINT_TRUE } else { 0 };
/// assert_eq!(false, foo.load(SeqCst));
/// ```
#[inline]
+ #[stable]
pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
let val = if val { UINT_TRUE } else { 0 };
/// assert_eq!(true, foo.load(SeqCst));
/// ```
#[inline]
+ #[stable]
pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
let val = if val { UINT_TRUE } else { 0 };
/// assert_eq!(false, foo.load(SeqCst));
/// ```
#[inline]
+ #[stable]
pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
let val = if val { UINT_TRUE } else { 0 };
/// assert_eq!(false, foo.load(SeqCst));
/// ```
#[inline]
+ #[stable]
pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
let val = if val { UINT_TRUE } else { 0 };
}
}
-#[stable]
impl AtomicInt {
/// Create a new `AtomicInt`
#[inline]
+ #[stable]
pub fn new(v: int) -> AtomicInt {
AtomicInt {v: UnsafeCell::new(v), nocopy: marker::NoCopy}
}
///
/// Fails if `order` is `Release` or `AcqRel`.
#[inline]
+ #[stable]
pub fn load(&self, order: Ordering) -> int {
unsafe { atomic_load(self.v.get() as *const int, order) }
}
///
/// Fails if `order` is `Acquire` or `AcqRel`.
#[inline]
+ #[stable]
pub fn store(&self, val: int, order: Ordering) {
unsafe { atomic_store(self.v.get(), val, order); }
}
/// Store a value, returning the old value
#[inline]
+ #[stable]
pub fn swap(&self, val: int, order: Ordering) -> int {
unsafe { atomic_swap(self.v.get(), val, order) }
}
/// replace the current value with `new`. Return the previous value.
/// If the return value is equal to `old` then the value was updated.
#[inline]
+ #[stable]
pub fn compare_and_swap(&self, old: int, new: int, order: Ordering) -> int {
unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) }
}
/// assert_eq!(10, foo.load(SeqCst));
/// ```
#[inline]
+ #[stable]
pub fn fetch_add(&self, val: int, order: Ordering) -> int {
unsafe { atomic_add(self.v.get(), val, order) }
}
/// assert_eq!(-10, foo.load(SeqCst));
/// ```
#[inline]
+ #[stable]
pub fn fetch_sub(&self, val: int, order: Ordering) -> int {
unsafe { atomic_sub(self.v.get(), val, order) }
}
/// assert_eq!(0b101101, foo.fetch_and(0b110011, SeqCst));
/// assert_eq!(0b100001, foo.load(SeqCst));
#[inline]
+ #[stable]
pub fn fetch_and(&self, val: int, order: Ordering) -> int {
unsafe { atomic_and(self.v.get(), val, order) }
}
/// assert_eq!(0b101101, foo.fetch_or(0b110011, SeqCst));
/// assert_eq!(0b111111, foo.load(SeqCst));
#[inline]
+ #[stable]
pub fn fetch_or(&self, val: int, order: Ordering) -> int {
unsafe { atomic_or(self.v.get(), val, order) }
}
/// assert_eq!(0b101101, foo.fetch_xor(0b110011, SeqCst));
/// assert_eq!(0b011110, foo.load(SeqCst));
#[inline]
+ #[stable]
pub fn fetch_xor(&self, val: int, order: Ordering) -> int {
unsafe { atomic_xor(self.v.get(), val, order) }
}
}
-#[stable]
impl AtomicUint {
/// Create a new `AtomicUint`
#[inline]
+ #[stable]
pub fn new(v: uint) -> AtomicUint {
AtomicUint { v: UnsafeCell::new(v), nocopy: marker::NoCopy }
}
///
/// Fails if `order` is `Release` or `AcqRel`.
#[inline]
+ #[stable]
pub fn load(&self, order: Ordering) -> uint {
unsafe { atomic_load(self.v.get() as *const uint, order) }
}
///
/// Fails if `order` is `Acquire` or `AcqRel`.
#[inline]
+ #[stable]
pub fn store(&self, val: uint, order: Ordering) {
unsafe { atomic_store(self.v.get(), val, order); }
}
/// Store a value, returning the old value
#[inline]
+ #[stable]
pub fn swap(&self, val: uint, order: Ordering) -> uint {
unsafe { atomic_swap(self.v.get(), val, order) }
}
/// replace the current value with `new`. Return the previous value.
/// If the return value is equal to `old` then the value was updated.
#[inline]
+ #[stable]
pub fn compare_and_swap(&self, old: uint, new: uint, order: Ordering) -> uint {
unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) }
}
/// assert_eq!(10, foo.load(SeqCst));
/// ```
#[inline]
+ #[stable]
pub fn fetch_add(&self, val: uint, order: Ordering) -> uint {
unsafe { atomic_add(self.v.get(), val, order) }
}
/// assert_eq!(0, foo.load(SeqCst));
/// ```
#[inline]
+ #[stable]
pub fn fetch_sub(&self, val: uint, order: Ordering) -> uint {
unsafe { atomic_sub(self.v.get(), val, order) }
}
/// assert_eq!(0b101101, foo.fetch_and(0b110011, SeqCst));
/// assert_eq!(0b100001, foo.load(SeqCst));
#[inline]
+ #[stable]
pub fn fetch_and(&self, val: uint, order: Ordering) -> uint {
unsafe { atomic_and(self.v.get(), val, order) }
}
/// assert_eq!(0b101101, foo.fetch_or(0b110011, SeqCst));
/// assert_eq!(0b111111, foo.load(SeqCst));
#[inline]
+ #[stable]
pub fn fetch_or(&self, val: uint, order: Ordering) -> uint {
unsafe { atomic_or(self.v.get(), val, order) }
}
/// assert_eq!(0b101101, foo.fetch_xor(0b110011, SeqCst));
/// assert_eq!(0b011110, foo.load(SeqCst));
#[inline]
+ #[stable]
pub fn fetch_xor(&self, val: uint, order: Ordering) -> uint {
unsafe { atomic_xor(self.v.get(), val, order) }
}
}
-#[stable]
impl<T> AtomicPtr<T> {
/// Create a new `AtomicPtr`
#[inline]
+ #[stable]
pub fn new(p: *mut T) -> AtomicPtr<T> {
AtomicPtr { p: UnsafeCell::new(p as uint), nocopy: marker::NoCopy }
}
///
/// Fails if `order` is `Release` or `AcqRel`.
#[inline]
+ #[stable]
pub fn load(&self, order: Ordering) -> *mut T {
unsafe {
atomic_load(self.p.get() as *const *mut T, order) as *mut T
///
/// Fails if `order` is `Acquire` or `AcqRel`.
#[inline]
+ #[stable]
pub fn store(&self, ptr: *mut T, order: Ordering) {
unsafe { atomic_store(self.p.get(), ptr as uint, order); }
}
/// Store a value, returning the old value
#[inline]
+ #[stable]
pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
unsafe { atomic_swap(self.p.get(), ptr as uint, order) as *mut T }
}
/// replace the current value with `new`. Return the previous value.
/// If the return value is equal to `old` then the value was updated.
#[inline]
+ #[stable]
pub fn compare_and_swap(&self, old: *mut T, new: *mut T, order: Ordering) -> *mut T {
unsafe {
atomic_compare_and_swap(self.p.get(), old as uint,
}
#[inline]
+#[stable]
unsafe fn atomic_load<T>(dst: *const T, order:Ordering) -> T {
match order {
Acquire => intrinsics::atomic_load_acq(dst),
}
#[inline]
+#[stable]
unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
match order {
Acquire => intrinsics::atomic_xchg_acq(dst, val),
/// Returns the old value (like __sync_fetch_and_add).
#[inline]
+#[stable]
unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T {
match order {
Acquire => intrinsics::atomic_xadd_acq(dst, val),
/// Returns the old value (like __sync_fetch_and_sub).
#[inline]
+#[stable]
unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T {
match order {
Acquire => intrinsics::atomic_xsub_acq(dst, val),
}
#[inline]
+#[stable]
unsafe fn atomic_compare_and_swap<T>(dst: *mut T, old:T, new:T, order: Ordering) -> T {
match order {
Acquire => intrinsics::atomic_cxchg_acq(dst, old, new),
}
#[inline]
+#[stable]
unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
match order {
Acquire => intrinsics::atomic_and_acq(dst, val),
}
#[inline]
+#[stable]
unsafe fn atomic_nand<T>(dst: *mut T, val: T, order: Ordering) -> T {
match order {
Acquire => intrinsics::atomic_nand_acq(dst, val),
#[inline]
+#[stable]
unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
match order {
Acquire => intrinsics::atomic_or_acq(dst, val),
#[inline]
+#[stable]
unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
match order {
Acquire => intrinsics::atomic_xor_acq(dst, val),