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:
commit
2e9f705b93
@ -18,28 +18,28 @@
|
||||
use std::kinds::marker;
|
||||
use cell::UnsafeCell;
|
||||
|
||||
/// An atomic boolean type.
|
||||
/// A boolean type which can be safely shared between threads.
|
||||
#[stable]
|
||||
pub struct AtomicBool {
|
||||
v: UnsafeCell<uint>,
|
||||
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]
|
||||
pub struct AtomicInt {
|
||||
v: UnsafeCell<int>,
|
||||
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]
|
||||
pub struct AtomicUint {
|
||||
v: UnsafeCell<uint>,
|
||||
nocopy: marker::NoCopy
|
||||
}
|
||||
|
||||
/// An unsafe atomic pointer. Only supports basic atomic operations
|
||||
/// A raw pointer type which can be safely shared between threads.
|
||||
#[stable]
|
||||
pub struct AtomicPtr<T> {
|
||||
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
|
||||
/// "relaxed" atomics allow all reorderings.
|
||||
///
|
||||
/// Rust's memory orderings are the same as in C++[1].
|
||||
///
|
||||
/// 1: http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync
|
||||
/// Rust's memory orderings are [the same as
|
||||
/// C++'s](http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync).
|
||||
#[stable]
|
||||
pub enum Ordering {
|
||||
/// No ordering constraints, only atomic operations
|
||||
/// 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
|
||||
/// 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
|
||||
/// in another thread.
|
||||
#[stable]
|
||||
Acquire,
|
||||
/// When coupled with a load, uses `Acquire` ordering, and with a store
|
||||
/// `Release` ordering
|
||||
/// `Release` ordering.
|
||||
#[stable]
|
||||
AcqRel,
|
||||
/// Like `AcqRel` with the additional guarantee that all threads see all
|
||||
/// sequentially consistent operations in the same order.
|
||||
#[stable]
|
||||
SeqCst
|
||||
SeqCst,
|
||||
}
|
||||
|
||||
/// An `AtomicBool` initialized to `false`
|
||||
/// An `AtomicBool` initialized to `false`.
|
||||
#[unstable = "may be renamed, pending conventions for static initalizers"]
|
||||
pub const INIT_ATOMIC_BOOL: AtomicBool =
|
||||
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"]
|
||||
pub const INIT_ATOMIC_INT: AtomicInt =
|
||||
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"]
|
||||
pub const INIT_ATOMIC_UINT: AtomicUint =
|
||||
AtomicUint { v: UnsafeCell { value: 0, }, nocopy: marker::NoCopy };
|
||||
@ -99,7 +98,16 @@ pub enum Ordering {
|
||||
const UINT_TRUE: uint = -1;
|
||||
|
||||
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]
|
||||
#[stable]
|
||||
pub fn new(v: bool) -> AtomicBool {
|
||||
@ -107,18 +115,42 @@ pub fn new(v: bool) -> AtomicBool {
|
||||
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 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]
|
||||
#[stable]
|
||||
pub fn load(&self, order: Ordering) -> bool {
|
||||
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
|
||||
///
|
||||
@ -131,7 +163,19 @@ pub fn store(&self, val: bool, order: Ordering) {
|
||||
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]
|
||||
#[stable]
|
||||
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 }
|
||||
}
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// `swap` also takes an `Ordering` argument which describes the memory ordering of this
|
||||
/// operation.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::sync::Arc;
|
||||
/// use std::sync::atomic::{AtomicBool, SeqCst};
|
||||
/// use std::task::deschedule;
|
||||
/// ```
|
||||
/// use std::sync::atomic::{AtomicBool, Ordering};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let spinlock = Arc::new(AtomicBool::new(false));
|
||||
/// let spinlock_clone = spinlock.clone();
|
||||
/// let some_bool = AtomicBool::new(true);
|
||||
///
|
||||
/// spawn(proc() {
|
||||
/// 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);
|
||||
/// }
|
||||
/// let value = some_bool.store(false, Ordering::Relaxed);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[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 }
|
||||
}
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// # Examples
|
||||
@ -223,10 +241,11 @@ pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
|
||||
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.
|
||||
///
|
||||
/// # Examples
|
||||
@ -255,10 +274,11 @@ pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
|
||||
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.
|
||||
///
|
||||
/// # Examples
|
||||
@ -286,10 +306,11 @@ pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
|
||||
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.
|
||||
///
|
||||
/// # Examples
|
||||
@ -319,25 +340,57 @@ pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
|
||||
}
|
||||
|
||||
impl AtomicInt {
|
||||
/// Create a new `AtomicInt`
|
||||
/// Creates a new `AtomicInt`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::sync::atomic::AtomicInt;
|
||||
///
|
||||
/// let atomic_forty_two = AtomicInt::new(42);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn new(v: int) -> AtomicInt {
|
||||
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 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]
|
||||
#[stable]
|
||||
pub fn load(&self, order: Ordering) -> int {
|
||||
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
|
||||
///
|
||||
@ -348,25 +401,48 @@ pub fn store(&self, val: int, order: Ordering) {
|
||||
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]
|
||||
#[stable]
|
||||
pub fn swap(&self, val: int, order: Ordering) -> int {
|
||||
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.
|
||||
///
|
||||
/// `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]
|
||||
#[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) }
|
||||
}
|
||||
|
||||
/// Add to the current value, returning the previous
|
||||
/// Add an int to the current value, returning the previous value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -383,7 +459,7 @@ pub fn fetch_add(&self, val: int, order: Ordering) -> int {
|
||||
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
|
||||
///
|
||||
@ -400,7 +476,7 @@ pub fn fetch_sub(&self, val: int, order: Ordering) -> int {
|
||||
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
|
||||
///
|
||||
@ -416,7 +492,7 @@ pub fn fetch_and(&self, val: int, order: Ordering) -> int {
|
||||
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
|
||||
///
|
||||
@ -432,7 +508,7 @@ pub fn fetch_or(&self, val: int, order: Ordering) -> int {
|
||||
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
|
||||
///
|
||||
@ -450,25 +526,57 @@ pub fn fetch_xor(&self, val: int, order: Ordering) -> int {
|
||||
}
|
||||
|
||||
impl AtomicUint {
|
||||
/// Create a new `AtomicUint`
|
||||
/// Creates a new `AtomicUint`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::sync::atomic::AtomicUint;
|
||||
///
|
||||
/// let atomic_forty_two = AtomicUint::new(42u);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn new(v: uint) -> AtomicUint {
|
||||
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 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]
|
||||
#[stable]
|
||||
pub fn load(&self, order: Ordering) -> uint {
|
||||
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
|
||||
///
|
||||
@ -479,25 +587,48 @@ pub fn store(&self, val: uint, order: Ordering) {
|
||||
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]
|
||||
#[stable]
|
||||
pub fn swap(&self, val: uint, order: Ordering) -> uint {
|
||||
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.
|
||||
///
|
||||
/// `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]
|
||||
#[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) }
|
||||
}
|
||||
|
||||
/// Add to the current value, returning the previous
|
||||
/// Add to the current uint, returning the previous value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -514,7 +645,7 @@ pub fn fetch_add(&self, val: uint, order: Ordering) -> uint {
|
||||
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
|
||||
///
|
||||
@ -531,7 +662,7 @@ pub fn fetch_sub(&self, val: uint, order: Ordering) -> uint {
|
||||
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
|
||||
///
|
||||
@ -547,7 +678,7 @@ pub fn fetch_and(&self, val: uint, order: Ordering) -> uint {
|
||||
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
|
||||
///
|
||||
@ -563,7 +694,7 @@ pub fn fetch_or(&self, val: uint, order: Ordering) -> uint {
|
||||
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
|
||||
///
|
||||
@ -581,18 +712,40 @@ pub fn fetch_xor(&self, val: uint, order: Ordering) -> uint {
|
||||
}
|
||||
|
||||
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]
|
||||
#[stable]
|
||||
pub fn new(p: *mut T) -> AtomicPtr<T> {
|
||||
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 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]
|
||||
#[stable]
|
||||
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
|
||||
///
|
||||
@ -612,18 +780,48 @@ 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
|
||||
/// 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]
|
||||
#[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 }
|
||||
}
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// `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]
|
||||
#[stable]
|
||||
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 if `order` is `Relaxed`
|
||||
/// Panics if `order` is `Relaxed`.
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn fence(order: Ordering) {
|
||||
|
Loading…
Reference in New Issue
Block a user