rollup merge of #19108: steveklabnik/doc_atomic_bool

I don't know enough about the free functions to give them better docs right now.
This commit is contained in:
Jakub Bukaj 2014-11-19 22:41:39 +01:00
commit 2e9f705b93

View File

@ -18,28 +18,28 @@
use std::kinds::marker; use std::kinds::marker;
use cell::UnsafeCell; use cell::UnsafeCell;
/// An atomic boolean type. /// A boolean type which can be safely shared between threads.
#[stable] #[stable]
pub struct AtomicBool { pub struct AtomicBool {
v: UnsafeCell<uint>, v: UnsafeCell<uint>,
nocopy: marker::NoCopy nocopy: marker::NoCopy
} }
/// A signed atomic integer type, supporting basic atomic arithmetic operations /// A signed integer type which can be safely shared between threads.
#[stable] #[stable]
pub struct AtomicInt { pub struct AtomicInt {
v: UnsafeCell<int>, v: UnsafeCell<int>,
nocopy: marker::NoCopy nocopy: marker::NoCopy
} }
/// An unsigned atomic integer type, supporting basic atomic arithmetic operations /// An unsigned integer type which can be safely shared between threads.
#[stable] #[stable]
pub struct AtomicUint { pub struct AtomicUint {
v: UnsafeCell<uint>, v: UnsafeCell<uint>,
nocopy: marker::NoCopy nocopy: marker::NoCopy
} }
/// An unsafe atomic pointer. Only supports basic atomic operations /// A raw pointer type which can be safely shared between threads.
#[stable] #[stable]
pub struct AtomicPtr<T> { pub struct AtomicPtr<T> {
p: UnsafeCell<uint>, p: UnsafeCell<uint>,
@ -54,43 +54,42 @@ pub struct AtomicPtr<T> {
/// to be moved either before or after the atomic operation; on the other end /// to be moved either before or after the atomic operation; on the other end
/// "relaxed" atomics allow all reorderings. /// "relaxed" atomics allow all reorderings.
/// ///
/// Rust's memory orderings are the same as in C++[1]. /// Rust's memory orderings are [the same as
/// /// C++'s](http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync).
/// 1: http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync
#[stable] #[stable]
pub enum Ordering { pub enum Ordering {
/// No ordering constraints, only atomic operations /// No ordering constraints, only atomic operations.
#[stable] #[stable]
Relaxed, Relaxed,
/// When coupled with a store, all previous writes become visible /// When coupled with a store, all previous writes become visible
/// to another thread that performs a load with `Acquire` ordering /// to another thread that performs a load with `Acquire` ordering
/// on the same value /// on the same value.
#[stable] #[stable]
Release, Release,
/// When coupled with a load, all subsequent loads will see data /// When coupled with a load, all subsequent loads will see data
/// written before a store with `Release` ordering on the same value /// written before a store with `Release` ordering on the same value
/// in another thread /// in another thread.
#[stable] #[stable]
Acquire, Acquire,
/// When coupled with a load, uses `Acquire` ordering, and with a store /// When coupled with a load, uses `Acquire` ordering, and with a store
/// `Release` ordering /// `Release` ordering.
#[stable] #[stable]
AcqRel, AcqRel,
/// Like `AcqRel` with the additional guarantee that all threads see all /// Like `AcqRel` with the additional guarantee that all threads see all
/// sequentially consistent operations in the same order. /// sequentially consistent operations in the same order.
#[stable] #[stable]
SeqCst SeqCst,
} }
/// An `AtomicBool` initialized to `false` /// An `AtomicBool` initialized to `false`.
#[unstable = "may be renamed, pending conventions for static initalizers"] #[unstable = "may be renamed, pending conventions for static initalizers"]
pub const INIT_ATOMIC_BOOL: AtomicBool = pub const INIT_ATOMIC_BOOL: AtomicBool =
AtomicBool { v: UnsafeCell { value: 0 }, nocopy: marker::NoCopy }; AtomicBool { v: UnsafeCell { value: 0 }, nocopy: marker::NoCopy };
/// An `AtomicInt` initialized to `0` /// An `AtomicInt` initialized to `0`.
#[unstable = "may be renamed, pending conventions for static initalizers"] #[unstable = "may be renamed, pending conventions for static initalizers"]
pub const INIT_ATOMIC_INT: AtomicInt = pub const INIT_ATOMIC_INT: AtomicInt =
AtomicInt { v: UnsafeCell { value: 0 }, nocopy: marker::NoCopy }; AtomicInt { v: UnsafeCell { value: 0 }, nocopy: marker::NoCopy };
/// An `AtomicUint` initialized to `0` /// An `AtomicUint` initialized to `0`.
#[unstable = "may be renamed, pending conventions for static initalizers"] #[unstable = "may be renamed, pending conventions for static initalizers"]
pub const INIT_ATOMIC_UINT: AtomicUint = pub const INIT_ATOMIC_UINT: AtomicUint =
AtomicUint { v: UnsafeCell { value: 0, }, nocopy: marker::NoCopy }; AtomicUint { v: UnsafeCell { value: 0, }, nocopy: marker::NoCopy };
@ -99,7 +98,16 @@ pub enum Ordering {
const UINT_TRUE: uint = -1; const UINT_TRUE: uint = -1;
impl AtomicBool { impl AtomicBool {
/// Create a new `AtomicBool` /// Creates a new `AtomicBool`.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::AtomicBool;
///
/// let atomic_true = AtomicBool::new(true);
/// let atomic_false = AtomicBool::new(false);
/// ```
#[inline] #[inline]
#[stable] #[stable]
pub fn new(v: bool) -> AtomicBool { pub fn new(v: bool) -> AtomicBool {
@ -107,18 +115,42 @@ pub fn new(v: bool) -> AtomicBool {
AtomicBool { v: UnsafeCell::new(val), nocopy: marker::NoCopy } AtomicBool { v: UnsafeCell::new(val), nocopy: marker::NoCopy }
} }
/// Load the value /// Loads a value from the bool.
///
/// `load` takes an `Ordering` argument which describes the memory ordering of this operation.
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if `order` is `Release` or `AcqRel`. /// Panics if `order` is `Release` or `AcqRel`.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicBool, Ordering};
///
/// let some_bool = AtomicBool::new(true);
///
/// let value = some_bool.load(Ordering::Relaxed);
/// ```
#[inline] #[inline]
#[stable] #[stable]
pub fn load(&self, order: Ordering) -> bool { pub fn load(&self, order: Ordering) -> bool {
unsafe { atomic_load(self.v.get() as *const uint, order) > 0 } unsafe { atomic_load(self.v.get() as *const uint, order) > 0 }
} }
/// Store the value /// Stores a value into the bool.
///
/// `store` takes an `Ordering` argument which describes the memory ordering of this operation.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicBool, Ordering};
///
/// let some_bool = AtomicBool::new(true);
///
/// some_bool.store(false, Ordering::Relaxed);
/// ```
/// ///
/// # Panics /// # Panics
/// ///
@ -131,7 +163,19 @@ pub fn store(&self, val: bool, order: Ordering) {
unsafe { atomic_store(self.v.get(), val, order); } unsafe { atomic_store(self.v.get(), val, order); }
} }
/// Store a value, returning the old value /// Stores a value into the bool, returning the old value.
///
/// `swap` takes an `Ordering` argument which describes the memory ordering of this operation.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicBool, Ordering};
///
/// let some_bool = AtomicBool::new(true);
///
/// let value = some_bool.swap(false, Ordering::Relaxed);
/// ```
#[inline] #[inline]
#[stable] #[stable]
pub fn swap(&self, val: bool, order: Ordering) -> bool { pub fn swap(&self, val: bool, order: Ordering) -> bool {
@ -140,48 +184,21 @@ pub fn swap(&self, val: bool, order: Ordering) -> bool {
unsafe { atomic_swap(self.v.get(), val, order) > 0 } unsafe { atomic_swap(self.v.get(), val, order) > 0 }
} }
/// If the current value is the same as expected, store a new value /// Stores a value into the bool if the current value is the same as the expected value.
/// ///
/// Compare the current value with `old`; if they are the same then
/// replace the current value with `new`. Return the previous value.
/// If the return value is equal to `old` then the value was updated. /// If the return value is equal to `old` then the value was updated.
/// ///
/// `swap` also takes an `Ordering` argument which describes the memory ordering of this
/// operation.
///
/// # Examples /// # Examples
/// ///
/// ```rust /// ```
/// use std::sync::Arc; /// use std::sync::atomic::{AtomicBool, Ordering};
/// use std::sync::atomic::{AtomicBool, SeqCst};
/// use std::task::deschedule;
/// ///
/// fn main() { /// let some_bool = AtomicBool::new(true);
/// let spinlock = Arc::new(AtomicBool::new(false));
/// let spinlock_clone = spinlock.clone();
/// ///
/// spawn(proc() { /// let value = some_bool.store(false, Ordering::Relaxed);
/// with_lock(&spinlock, || println!("task 1 in lock"));
/// });
///
/// spawn(proc() {
/// with_lock(&spinlock_clone, || println!("task 2 in lock"));
/// });
/// }
///
/// fn with_lock(spinlock: &Arc<AtomicBool>, f: || -> ()) {
/// // CAS loop until we are able to replace `false` with `true`
/// while spinlock.compare_and_swap(false, true, SeqCst) != false {
/// // Since tasks may not be preemptive (if they are green threads)
/// // yield to the scheduler to let the other task run. Low level
/// // concurrent code needs to take into account Rust's two threading
/// // models.
/// deschedule();
/// }
///
/// // Now we have the spinlock
/// f();
///
/// // Release the lock
/// spinlock.store(false, SeqCst);
/// }
/// ``` /// ```
#[inline] #[inline]
#[stable] #[stable]
@ -192,10 +209,11 @@ pub fn compare_and_swap(&self, old: bool, new: bool, order: Ordering) -> bool {
unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) > 0 } unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) > 0 }
} }
/// A logical "and" operation /// Logical "and" with a boolean value.
///
/// Performs a logical "and" operation on the current value and the argument `val`, and sets
/// the new value to the result.
/// ///
/// Performs a logical "and" operation on the current value and the
/// argument `val`, and sets the new value to the result.
/// Returns the previous value. /// Returns the previous value.
/// ///
/// # Examples /// # Examples
@ -223,10 +241,11 @@ pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
unsafe { atomic_and(self.v.get(), val, order) > 0 } unsafe { atomic_and(self.v.get(), val, order) > 0 }
} }
/// A logical "nand" operation /// Logical "nand" with a boolean value.
///
/// Performs a logical "nand" operation on the current value and the argument `val`, and sets
/// the new value to the result.
/// ///
/// Performs a logical "nand" operation on the current value and the
/// argument `val`, and sets the new value to the result.
/// Returns the previous value. /// Returns the previous value.
/// ///
/// # Examples /// # Examples
@ -255,10 +274,11 @@ pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
unsafe { atomic_nand(self.v.get(), val, order) > 0 } unsafe { atomic_nand(self.v.get(), val, order) > 0 }
} }
/// A logical "or" operation /// Logical "or" with a boolean value.
///
/// Performs a logical "or" operation on the current value and the argument `val`, and sets the
/// new value to the result.
/// ///
/// Performs a logical "or" operation on the current value and the
/// argument `val`, and sets the new value to the result.
/// Returns the previous value. /// Returns the previous value.
/// ///
/// # Examples /// # Examples
@ -286,10 +306,11 @@ pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
unsafe { atomic_or(self.v.get(), val, order) > 0 } unsafe { atomic_or(self.v.get(), val, order) > 0 }
} }
/// A logical "xor" operation /// Logical "xor" with a boolean value.
///
/// Performs a logical "xor" operation on the current value and the argument `val`, and sets
/// the new value to the result.
/// ///
/// Performs a logical "xor" operation on the current value and the
/// argument `val`, and sets the new value to the result.
/// Returns the previous value. /// Returns the previous value.
/// ///
/// # Examples /// # Examples
@ -319,25 +340,57 @@ pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
} }
impl AtomicInt { impl AtomicInt {
/// Create a new `AtomicInt` /// Creates a new `AtomicInt`.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::AtomicInt;
///
/// let atomic_forty_two = AtomicInt::new(42);
/// ```
#[inline] #[inline]
#[stable] #[stable]
pub fn new(v: int) -> AtomicInt { pub fn new(v: int) -> AtomicInt {
AtomicInt {v: UnsafeCell::new(v), nocopy: marker::NoCopy} AtomicInt {v: UnsafeCell::new(v), nocopy: marker::NoCopy}
} }
/// Load the value /// Loads a value from the int.
///
/// `load` takes an `Ordering` argument which describes the memory ordering of this operation.
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if `order` is `Release` or `AcqRel`. /// Panics if `order` is `Release` or `AcqRel`.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicInt, Ordering};
///
/// let some_int = AtomicInt::new(5);
///
/// let value = some_int.load(Ordering::Relaxed);
/// ```
#[inline] #[inline]
#[stable] #[stable]
pub fn load(&self, order: Ordering) -> int { pub fn load(&self, order: Ordering) -> int {
unsafe { atomic_load(self.v.get() as *const int, order) } unsafe { atomic_load(self.v.get() as *const int, order) }
} }
/// Store the value /// Stores a value into the int.
///
/// `store` takes an `Ordering` argument which describes the memory ordering of this operation.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicInt, Ordering};
///
/// let some_int = AtomicInt::new(5);
///
/// some_int.store(10, Ordering::Relaxed);
/// ```
/// ///
/// # Panics /// # Panics
/// ///
@ -348,25 +401,48 @@ pub fn store(&self, val: int, order: Ordering) {
unsafe { atomic_store(self.v.get(), val, order); } unsafe { atomic_store(self.v.get(), val, order); }
} }
/// Store a value, returning the old value /// Stores a value into the int, returning the old value.
///
/// `swap` takes an `Ordering` argument which describes the memory ordering of this operation.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicInt, Ordering};
///
/// let some_int = AtomicInt::new(5);
///
/// let value = some_int.swap(10, Ordering::Relaxed);
/// ```
#[inline] #[inline]
#[stable] #[stable]
pub fn swap(&self, val: int, order: Ordering) -> int { pub fn swap(&self, val: int, order: Ordering) -> int {
unsafe { atomic_swap(self.v.get(), val, order) } unsafe { atomic_swap(self.v.get(), val, order) }
} }
/// If the current value is the same as expected, store a new value /// Stores a value into the int if the current value is the same as the expected value.
/// ///
/// Compare the current value with `old`; if they are the same then
/// replace the current value with `new`. Return the previous value.
/// If the return value is equal to `old` then the value was updated. /// If the return value is equal to `old` then the value was updated.
///
/// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of
/// this operation.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicInt, Ordering};
///
/// let some_int = AtomicInt::new(5);
///
/// let value = some_int.compare_and_swap(5, 10, Ordering::Relaxed);
/// ```
#[inline] #[inline]
#[stable] #[stable]
pub fn compare_and_swap(&self, old: int, new: int, order: Ordering) -> int { pub fn compare_and_swap(&self, old: int, new: int, order: Ordering) -> int {
unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) } unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) }
} }
/// Add to the current value, returning the previous /// Add an int to the current value, returning the previous value.
/// ///
/// # Examples /// # Examples
/// ///
@ -383,7 +459,7 @@ pub fn fetch_add(&self, val: int, order: Ordering) -> int {
unsafe { atomic_add(self.v.get(), val, order) } unsafe { atomic_add(self.v.get(), val, order) }
} }
/// Subtract from the current value, returning the previous /// Subtract an int from the current value, returning the previous value.
/// ///
/// # Examples /// # Examples
/// ///
@ -400,7 +476,7 @@ pub fn fetch_sub(&self, val: int, order: Ordering) -> int {
unsafe { atomic_sub(self.v.get(), val, order) } unsafe { atomic_sub(self.v.get(), val, order) }
} }
/// Bitwise and with the current value, returning the previous /// Bitwise and with the current int, returning the previous value.
/// ///
/// # Examples /// # Examples
/// ///
@ -416,7 +492,7 @@ pub fn fetch_and(&self, val: int, order: Ordering) -> int {
unsafe { atomic_and(self.v.get(), val, order) } unsafe { atomic_and(self.v.get(), val, order) }
} }
/// Bitwise or with the current value, returning the previous /// Bitwise or with the current int, returning the previous value.
/// ///
/// # Examples /// # Examples
/// ///
@ -432,7 +508,7 @@ pub fn fetch_or(&self, val: int, order: Ordering) -> int {
unsafe { atomic_or(self.v.get(), val, order) } unsafe { atomic_or(self.v.get(), val, order) }
} }
/// Bitwise xor with the current value, returning the previous /// Bitwise xor with the current int, returning the previous value.
/// ///
/// # Examples /// # Examples
/// ///
@ -450,25 +526,57 @@ pub fn fetch_xor(&self, val: int, order: Ordering) -> int {
} }
impl AtomicUint { impl AtomicUint {
/// Create a new `AtomicUint` /// Creates a new `AtomicUint`.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::AtomicUint;
///
/// let atomic_forty_two = AtomicUint::new(42u);
/// ```
#[inline] #[inline]
#[stable] #[stable]
pub fn new(v: uint) -> AtomicUint { pub fn new(v: uint) -> AtomicUint {
AtomicUint { v: UnsafeCell::new(v), nocopy: marker::NoCopy } AtomicUint { v: UnsafeCell::new(v), nocopy: marker::NoCopy }
} }
/// Load the value /// Loads a value from the uint.
///
/// `load` takes an `Ordering` argument which describes the memory ordering of this operation.
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if `order` is `Release` or `AcqRel`. /// Panics if `order` is `Release` or `AcqRel`.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicUint, Ordering};
///
/// let some_uint = AtomicUint::new(5);
///
/// let value = some_uint.load(Ordering::Relaxed);
/// ```
#[inline] #[inline]
#[stable] #[stable]
pub fn load(&self, order: Ordering) -> uint { pub fn load(&self, order: Ordering) -> uint {
unsafe { atomic_load(self.v.get() as *const uint, order) } unsafe { atomic_load(self.v.get() as *const uint, order) }
} }
/// Store the value /// Stores a value into the uint.
///
/// `store` takes an `Ordering` argument which describes the memory ordering of this operation.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicUint, Ordering};
///
/// let some_uint = AtomicUint::new(5);
///
/// some_uint.store(10, Ordering::Relaxed);
/// ```
/// ///
/// # Panics /// # Panics
/// ///
@ -479,25 +587,48 @@ pub fn store(&self, val: uint, order: Ordering) {
unsafe { atomic_store(self.v.get(), val, order); } unsafe { atomic_store(self.v.get(), val, order); }
} }
/// Store a value, returning the old value /// Stores a value into the uint, returning the old value.
///
/// `swap` takes an `Ordering` argument which describes the memory ordering of this operation.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicUint, Ordering};
///
/// let some_uint = AtomicUint::new(5);
///
/// let value = some_uint.swap(10, Ordering::Relaxed);
/// ```
#[inline] #[inline]
#[stable] #[stable]
pub fn swap(&self, val: uint, order: Ordering) -> uint { pub fn swap(&self, val: uint, order: Ordering) -> uint {
unsafe { atomic_swap(self.v.get(), val, order) } unsafe { atomic_swap(self.v.get(), val, order) }
} }
/// If the current value is the same as expected, store a new value /// Stores a value into the uint if the current value is the same as the expected value.
/// ///
/// Compare the current value with `old`; if they are the same then
/// replace the current value with `new`. Return the previous value.
/// If the return value is equal to `old` then the value was updated. /// If the return value is equal to `old` then the value was updated.
///
/// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of
/// this operation.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicUint, Ordering};
///
/// let some_uint = AtomicUint::new(5);
///
/// let value = some_uint.compare_and_swap(5, 10, Ordering::Relaxed);
/// ```
#[inline] #[inline]
#[stable] #[stable]
pub fn compare_and_swap(&self, old: uint, new: uint, order: Ordering) -> uint { pub fn compare_and_swap(&self, old: uint, new: uint, order: Ordering) -> uint {
unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) } unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) }
} }
/// Add to the current value, returning the previous /// Add to the current uint, returning the previous value.
/// ///
/// # Examples /// # Examples
/// ///
@ -514,7 +645,7 @@ pub fn fetch_add(&self, val: uint, order: Ordering) -> uint {
unsafe { atomic_add(self.v.get(), val, order) } unsafe { atomic_add(self.v.get(), val, order) }
} }
/// Subtract from the current value, returning the previous /// Subtract from the current uint, returning the previous value.
/// ///
/// # Examples /// # Examples
/// ///
@ -531,7 +662,7 @@ pub fn fetch_sub(&self, val: uint, order: Ordering) -> uint {
unsafe { atomic_sub(self.v.get(), val, order) } unsafe { atomic_sub(self.v.get(), val, order) }
} }
/// Bitwise and with the current value, returning the previous /// Bitwise and with the current uint, returning the previous value.
/// ///
/// # Examples /// # Examples
/// ///
@ -547,7 +678,7 @@ pub fn fetch_and(&self, val: uint, order: Ordering) -> uint {
unsafe { atomic_and(self.v.get(), val, order) } unsafe { atomic_and(self.v.get(), val, order) }
} }
/// Bitwise or with the current value, returning the previous /// Bitwise or with the current uint, returning the previous value.
/// ///
/// # Examples /// # Examples
/// ///
@ -563,7 +694,7 @@ pub fn fetch_or(&self, val: uint, order: Ordering) -> uint {
unsafe { atomic_or(self.v.get(), val, order) } unsafe { atomic_or(self.v.get(), val, order) }
} }
/// Bitwise xor with the current value, returning the previous /// Bitwise xor with the current uint, returning the previous value.
/// ///
/// # Examples /// # Examples
/// ///
@ -581,18 +712,40 @@ pub fn fetch_xor(&self, val: uint, order: Ordering) -> uint {
} }
impl<T> AtomicPtr<T> { impl<T> AtomicPtr<T> {
/// Create a new `AtomicPtr` /// Creates a new `AtomicPtr`.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::AtomicPtr;
///
/// let ptr = &mut 5i;
/// let atomic_ptr = AtomicPtr::new(ptr);
/// ```
#[inline] #[inline]
#[stable] #[stable]
pub fn new(p: *mut T) -> AtomicPtr<T> { pub fn new(p: *mut T) -> AtomicPtr<T> {
AtomicPtr { p: UnsafeCell::new(p as uint), nocopy: marker::NoCopy } AtomicPtr { p: UnsafeCell::new(p as uint), nocopy: marker::NoCopy }
} }
/// Load the value /// Loads a value from the pointer.
///
/// `load` takes an `Ordering` argument which describes the memory ordering of this operation.
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if `order` is `Release` or `AcqRel`. /// Panics if `order` is `Release` or `AcqRel`.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicPtr, Ordering};
///
/// let ptr = &mut 5i;
/// let some_ptr = AtomicPtr::new(ptr);
///
/// let value = some_ptr.load(Ordering::Relaxed);
/// ```
#[inline] #[inline]
#[stable] #[stable]
pub fn load(&self, order: Ordering) -> *mut T { pub fn load(&self, order: Ordering) -> *mut T {
@ -601,7 +754,22 @@ pub fn load(&self, order: Ordering) -> *mut T {
} }
} }
/// Store the value /// Stores a value into the pointer.
///
/// `store` takes an `Ordering` argument which describes the memory ordering of this operation.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicPtr, Ordering};
///
/// let ptr = &mut 5i;
/// let some_ptr = AtomicPtr::new(ptr);
///
/// let other_ptr = &mut 10i;
///
/// some_ptr.store(other_ptr, Ordering::Relaxed);
/// ```
/// ///
/// # Panics /// # Panics
/// ///
@ -612,18 +780,48 @@ pub fn store(&self, ptr: *mut T, order: Ordering) {
unsafe { atomic_store(self.p.get(), ptr as uint, order); } unsafe { atomic_store(self.p.get(), ptr as uint, order); }
} }
/// Store a value, returning the old value /// Stores a value into the pointer, returning the old value.
///
/// `swap` takes an `Ordering` argument which describes the memory ordering of this operation.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicPtr, Ordering};
///
/// let ptr = &mut 5i;
/// let some_ptr = AtomicPtr::new(ptr);
///
/// let other_ptr = &mut 10i;
///
/// let value = some_ptr.swap(other_ptr, Ordering::Relaxed);
/// ```
#[inline] #[inline]
#[stable] #[stable]
pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T { pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
unsafe { atomic_swap(self.p.get(), ptr as uint, order) as *mut T } unsafe { atomic_swap(self.p.get(), ptr as uint, order) as *mut T }
} }
/// If the current value is the same as expected, store a new value /// Stores a value into the pointer if the current value is the same as the expected value.
/// ///
/// Compare the current value with `old`; if they are the same then
/// replace the current value with `new`. Return the previous value.
/// If the return value is equal to `old` then the value was updated. /// If the return value is equal to `old` then the value was updated.
///
/// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of
/// this operation.
///
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicPtr, Ordering};
///
/// let ptr = &mut 5i;
/// let some_ptr = AtomicPtr::new(ptr);
///
/// let other_ptr = &mut 10i;
/// let another_ptr = &mut 10i;
///
/// let value = some_ptr.compare_and_swap(other_ptr, another_ptr, Ordering::Relaxed);
/// ```
#[inline] #[inline]
#[stable] #[stable]
pub fn compare_and_swap(&self, old: *mut T, new: *mut T, order: Ordering) -> *mut T { pub fn compare_and_swap(&self, old: *mut T, new: *mut T, order: Ordering) -> *mut T {
@ -777,7 +975,7 @@ unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if `order` is `Relaxed` /// Panics if `order` is `Relaxed`.
#[inline] #[inline]
#[stable] #[stable]
pub fn fence(order: Ordering) { pub fn fence(order: Ordering) {