Struct Atomic
struct Atomic<T: ?Sized + Pointable> { ... }
An atomic pointer that can be safely shared between threads.
The pointer must be properly aligned. Since it is aligned, a tag can be stored into the unused
least significant bits of the address. For example, the tag for a pointer to a sized type T
should be less than (1 << mem::align_of::<T>().trailing_zeros()).
Any method that loads the pointer must be passed a reference to a Guard.
Crossbeam supports dynamically sized types. See Pointable for details.
Implementations
impl<T> Atomic<T>
fn new(init: T) -> Atomic<T>Allocates
valueon the heap and returns a new atomic pointer pointing to it.Examples
use Atomic; let a = new; # unsafe // avoid leak
impl<T: ?Sized + Pointable> Atomic<T>
fn init(init: <T as >::Init) -> Atomic<T>Allocates
valueon the heap and returns a new atomic pointer pointing to it.Examples
use Atomic; let a = init; # unsafe // avoid leakconst fn null() -> Atomic<T>Returns a new null atomic pointer.
Examples
use Atomic; let a = null;fn load<'g>(self: &Self, ord: Ordering, _: &'g Guard) -> Shared<'g, T>Loads a
Sharedfrom the atomic pointer.This method takes an
Orderingargument which describes the memory ordering of this operation.Examples
use ; use SeqCst; let a = new; let guard = &pin; let p = a.load; # unsafe // avoid leakfn load_consume<'g>(self: &Self, _: &'g Guard) -> Shared<'g, T>Loads a
Sharedfrom the atomic pointer using a "consume" memory ordering.This is similar to the "acquire" ordering, except that an ordering is only guaranteed with operations that "depend on" the result of the load. However consume loads are usually much faster than acquire loads on architectures with a weak memory model since they don't require memory fence instructions.
The exact definition of "depend on" is a bit vague, but it works as you would expect in practice since a lot of software, especially the Linux kernel, rely on this behavior.
Examples
use ; let a = new; let guard = &pin; let p = a.load_consume; # unsafe // avoid leakfn store<P: Pointer<T>>(self: &Self, new: P, ord: Ordering)Stores a
SharedorOwnedpointer into the atomic pointer.This method takes an
Orderingargument which describes the memory ordering of this operation.Examples
use ; use SeqCst; let a = new; # unsafe // avoid leak a.store; a.store; # unsafe // avoid leakfn swap<'g, P: Pointer<T>>(self: &Self, new: P, ord: Ordering, _: &'g Guard) -> Shared<'g, T>Stores a
SharedorOwnedpointer into the atomic pointer, returning the previousShared.This method takes an
Orderingargument which describes the memory ordering of this operation.Examples
use ; use SeqCst; let a = new; let guard = &pin; let p = a.swap; # unsafe // avoid leakfn compare_exchange<'g, P>(self: &Self, current: Shared<'_, T>, new: P, success: Ordering, failure: Ordering, _: &'g Guard) -> Result<Shared<'g, T>, CompareExchangeError<'g, T, P>> where P: Pointer<T>Stores the pointer
new(eitherSharedorOwned) into the atomic pointer if the current value is the same ascurrent. The tag is also taken into account, so two pointers to the same object, but with different tags, will not be considered equal.The return value is a result indicating whether the new pointer was written. On success the pointer that was written is returned. On failure the actual current value and
neware returned.This method takes two
Orderingarguments to describe the memory ordering of this operation.successdescribes the required ordering for the read-modify-write operation that takes place if the comparison withcurrentsucceeds.failuredescribes the required ordering for the load operation that takes place when the comparison fails. UsingAcquireas success ordering makes the store part of this operationRelaxed, and usingReleasemakes the successful loadRelaxed. The failure ordering can only beSeqCst,AcquireorRelaxedand must be equivalent to or weaker than the success ordering.Examples
use ; use SeqCst; let a = new; let guard = &pin; let curr = a.load; let res1 = a.compare_exchange; let res2 = a.compare_exchange; # unsafe // avoid leakfn compare_exchange_weak<'g, P>(self: &Self, current: Shared<'_, T>, new: P, success: Ordering, failure: Ordering, _: &'g Guard) -> Result<Shared<'g, T>, CompareExchangeError<'g, T, P>> where P: Pointer<T>Stores the pointer
new(eitherSharedorOwned) into the atomic pointer if the current value is the same ascurrent. The tag is also taken into account, so two pointers to the same object, but with different tags, will not be considered equal.Unlike
compare_exchange, this method is allowed to spuriously fail even when comparison succeeds, which can result in more efficient code on some platforms. The return value is a result indicating whether the new pointer was written. On success the pointer that was written is returned. On failure the actual current value andneware returned.This method takes two
Orderingarguments to describe the memory ordering of this operation.successdescribes the required ordering for the read-modify-write operation that takes place if the comparison withcurrentsucceeds.failuredescribes the required ordering for the load operation that takes place when the comparison fails. UsingAcquireas success ordering makes the store part of this operationRelaxed, and usingReleasemakes the successful loadRelaxed. The failure ordering can only beSeqCst,AcquireorRelaxedand must be equivalent to or weaker than the success ordering.Examples
use ; use SeqCst; let a = new; let guard = &pin; let mut new = new; let mut ptr = a.load; # unsafe // avoid leak loop let mut curr = a.load; loop # unsafe // avoid leakfn fetch_update<'g, F>(self: &Self, set_order: Ordering, fail_order: Ordering, guard: &'g Guard, func: F) -> Result<Shared<'g, T>, Shared<'g, T>> where F: FnMut(Shared<'g, T>) -> Option<Shared<'g, T>>Fetches the pointer, and then applies a function to it that returns a new value. Returns a
ResultofOk(previous_value)if the function returnedSome, elseErr(_).Note that the given function may be called multiple times if the value has been changed by other threads in the meantime, as long as the function returns
Some(_), but the function will have been applied only once to the stored value.fetch_updatetakes twoOrderingarguments to describe the memory ordering of this operation. The first describes the required ordering for when the operation finally succeeds while the second describes the required ordering for loads. These correspond to the success and failure orderings ofAtomic::compare_exchangerespectively.Using
Acquireas success ordering makes the store part of this operationRelaxed, and usingReleasemakes the final successful loadRelaxed. The (failed) load ordering can only beSeqCst,AcquireorRelaxedand must be equivalent to or weaker than the success ordering.Examples
use ; use SeqCst; let a = new; let guard = &pin; let res1 = a.fetch_update; assert!; let res2 = a.fetch_update; assert!; # unsafe // avoid leakfn compare_and_set<'g, O, P>(self: &Self, current: Shared<'_, T>, new: P, ord: O, guard: &'g Guard) -> Result<Shared<'g, T>, CompareAndSetError<'g, T, P>> where O: CompareAndSetOrdering, P: Pointer<T>Stores the pointer
new(eitherSharedorOwned) into the atomic pointer if the current value is the same ascurrent. The tag is also taken into account, so two pointers to the same object, but with different tags, will not be considered equal.The return value is a result indicating whether the new pointer was written. On success the pointer that was written is returned. On failure the actual current value and
neware returned.This method takes a
CompareAndSetOrderingargument which describes the memory ordering of this operation.Migrating to
compare_exchangecompare_and_setis equivalent tocompare_exchangewith the following mapping for memory orderings:Original Success Failure Relaxed Relaxed Relaxed Acquire Acquire Acquire Release Release Relaxed AcqRel AcqRel Acquire SeqCst SeqCst SeqCst Examples
# use ; use SeqCst; let a = new; let guard = &pin; let curr = a.load; let res1 = a.compare_and_set; let res2 = a.compare_and_set; # unsafe // avoid leakfn compare_and_set_weak<'g, O, P>(self: &Self, current: Shared<'_, T>, new: P, ord: O, guard: &'g Guard) -> Result<Shared<'g, T>, CompareAndSetError<'g, T, P>> where O: CompareAndSetOrdering, P: Pointer<T>Stores the pointer
new(eitherSharedorOwned) into the atomic pointer if the current value is the same ascurrent. The tag is also taken into account, so two pointers to the same object, but with different tags, will not be considered equal.Unlike
compare_and_set, this method is allowed to spuriously fail even when comparison succeeds, which can result in more efficient code on some platforms. The return value is a result indicating whether the new pointer was written. On success the pointer that was written is returned. On failure the actual current value andneware returned.This method takes a
CompareAndSetOrderingargument which describes the memory ordering of this operation.Migrating to
compare_exchange_weakcompare_and_set_weakis equivalent tocompare_exchange_weakwith the following mapping for memory orderings:Original Success Failure Relaxed Relaxed Relaxed Acquire Acquire Acquire Release Release Relaxed AcqRel AcqRel Acquire SeqCst SeqCst SeqCst Examples
# use ; use SeqCst; let a = new; let guard = &pin; let mut new = new; let mut ptr = a.load; # unsafe // avoid leak loop let mut curr = a.load; loop # unsafe // avoid leakfn fetch_and<'g>(self: &Self, val: usize, ord: Ordering, _: &'g Guard) -> Shared<'g, T>Bitwise "and" with the current tag.
Performs a bitwise "and" operation on the current tag and the argument
val, and sets the new tag to the result. Returns the previous pointer.This method takes an
Orderingargument which describes the memory ordering of this operation.Examples
use ; use SeqCst; let a = from; let guard = &pin; assert_eq!; assert_eq!;fn fetch_or<'g>(self: &Self, val: usize, ord: Ordering, _: &'g Guard) -> Shared<'g, T>Bitwise "or" with the current tag.
Performs a bitwise "or" operation on the current tag and the argument
val, and sets the new tag to the result. Returns the previous pointer.This method takes an
Orderingargument which describes the memory ordering of this operation.Examples
use ; use SeqCst; let a = from; let guard = &pin; assert_eq!; assert_eq!;fn fetch_xor<'g>(self: &Self, val: usize, ord: Ordering, _: &'g Guard) -> Shared<'g, T>Bitwise "xor" with the current tag.
Performs a bitwise "xor" operation on the current tag and the argument
val, and sets the new tag to the result. Returns the previous pointer.This method takes an
Orderingargument which describes the memory ordering of this operation.Examples
use ; use SeqCst; let a = from; let guard = &pin; assert_eq!; assert_eq!;unsafe fn into_owned(self: Self) -> Owned<T>Takes ownership of the pointee.
This consumes the atomic and converts it into
Owned. AsAtomicdoesn't have a destructor and doesn't drop the pointee whileOwneddoes, this is suitable for destructors of data structures.Panics
Panics if this pointer is null, but only in debug mode.
Safety
This method may be called only if the pointer is valid and nobody else is holding a reference to the same object.
Examples
# use mem; # use Atomic;unsafe fn try_into_owned(self: Self) -> Option<Owned<T>>Takes ownership of the pointee if it is non-null.
This consumes the atomic and converts it into
Owned. AsAtomicdoesn't have a destructor and doesn't drop the pointee whileOwneddoes, this is suitable for destructors of data structures.Safety
This method may be called only if the pointer is valid and nobody else is holding a reference to the same object, or the pointer is null.
Examples
# use mem; # use Atomic;
impl<'g, T: ?Sized + Pointable> From for Atomic<T>
fn from(ptr: Shared<'g, T>) -> SelfReturns a new atomic pointer pointing to
ptr.Examples
use ; let a = from;
impl<T> Any for Atomic<T>
fn type_id(self: &Self) -> TypeId
impl<T> Borrow for Atomic<T>
fn borrow(self: &Self) -> &T
impl<T> BorrowMut for Atomic<T>
fn borrow_mut(self: &mut Self) -> &mut T
impl<T> CloneToUninit for Atomic<T>
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8)
impl<T> Freeze for Atomic<T>
impl<T> From for Atomic<T>
fn from(t: T) -> Self
impl<T> From for Atomic<T>
fn from(t: T) -> TReturns the argument unchanged.
impl<T> From for Atomic<T>
fn from(b: Box<T>) -> Self
impl<T> From for Atomic<T>
fn from(raw: *const T) -> SelfReturns a new atomic pointer pointing to
raw.Examples
use ptr; use Atomic; let a = from;
impl<T> From for Atomic<T>
fn from(t: never) -> T
impl<T> Pointable for Atomic<T>
unsafe fn init(init: <T as Pointable>::Init) -> usizeunsafe fn deref<'a>(ptr: usize) -> &'a Tunsafe fn deref_mut<'a>(ptr: usize) -> &'a mut Tunsafe fn drop(ptr: usize)
impl<T> RefUnwindSafe for Atomic<T>
impl<T> ToOwned for Atomic<T>
fn to_owned(self: &Self) -> Tfn clone_into(self: &Self, target: &mut T)
impl<T> Unpin for Atomic<T>
impl<T> UnsafeUnpin for Atomic<T>
impl<T> UnwindSafe for Atomic<T>
impl<T, U> Into for Atomic<T>
fn into(self: Self) -> UCalls
U::from(self).That is, this conversion is whatever the implementation of
[From]<T> for Uchooses to do.
impl<T, U> TryFrom for Atomic<T>
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
impl<T, U> TryInto for Atomic<T>
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>
impl<T: ?Sized + Pointable + Send + Sync> Send for Atomic<T>
impl<T: ?Sized + Pointable + Send + Sync> Sync for Atomic<T>
impl<T: ?Sized + Pointable> Clone for Atomic<T>
fn clone(self: &Self) -> SelfReturns a copy of the atomic value.
Note that a
Relaxedload is used here. If you need synchronization, use it with other atomics or fences.
impl<T: ?Sized + Pointable> Debug for Atomic<T>
fn fmt(self: &Self, f: &mut Formatter<'_>) -> Result
impl<T: ?Sized + Pointable> Default for Atomic<T>
fn default() -> Self
impl<T: ?Sized + Pointable> From for Atomic<T>
fn from(owned: Owned<T>) -> SelfReturns a new atomic pointer pointing to
owned.Examples
use ; let a = from; # unsafe // avoid leak
impl<T: ?Sized + Pointable> Pointer for Atomic<T>
fn fmt(self: &Self, f: &mut Formatter<'_>) -> Result