Struct AtomicI32
struct AtomicI32 { ... }
An integer type which can be safely shared between threads.
This type has the same
size and bit validity
as the underlying integer type, [i32].
However, the alignment of this type is always equal to its size, even on targets where i32 has a lesser alignment.
For more about the differences between atomic types and non-atomic types as well as information about the portability of this type, please see the module-level documentation.
Note: This type is only available on platforms that support
atomic loads and stores of [i32].
Implementations
impl AtomicI32
const fn new(v: i32) -> SelfCreates a new atomic integer.
Examples
use AtomicI32; let atomic_forty_two = new;unsafe const fn from_ptr<'a>(ptr: *mut i32) -> &'a AtomicI32Creates a new reference to an atomic integer from a pointer.
Examples
use ; // Get a pointer to an allocated value let ptr: *mut i32 = Boxinto_raw; assert!; // It's ok to non-atomically access the value behind `ptr`, // since the reference to the atomic ended its lifetime in the block above assert_eq!; // Deallocate the value unsafeSafety
ptrmust be aligned toalign_of::<AtomicI32>()(note that on some platforms this can be bigger thanalign_of::<i32>()).ptrmust be valid for both reads and writes for the whole lifetime'a.- You must adhere to the Memory model for atomic accesses. In particular, it is not allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different sizes, without synchronization.
fn get_mut(self: &mut Self) -> &mut i32Returns a mutable reference to the underlying integer.
This is safe because the mutable reference guarantees that no other threads are concurrently accessing the atomic data.
Examples
use ; let mut some_var = new; assert_eq!; *some_var.get_mut = 5; assert_eq!;fn from_mut(v: &mut i32) -> &mut SelfGet atomic access to a
&mut i32.Note: This function is only available on targets where
AtomicI32has the same alignment asi32.Examples
use ; let mut some_int = 123; let a = from_mut; a.store; assert_eq!;fn get_mut_slice(this: &mut [Self]) -> &mut [i32]Get non-atomic access to a
&mut [AtomicI32]sliceThis is safe because the mutable reference guarantees that no other threads are concurrently accessing the atomic data.
Examples
#![feature(atomic_from_mut)] use std::sync::atomic::{AtomicI32, Ordering}; let mut some_ints = [const { AtomicI32::new(0) }; 10]; let view: &mut [i32] = AtomicI32::get_mut_slice(&mut some_ints); assert_eq!(view, [0; 10]); view .iter_mut() .enumerate() .for_each(|(idx, int)| *int = idx as _); std::thread::scope(|s| { some_ints .iter() .enumerate() .for_each(|(idx, int)| { s.spawn(move || assert_eq!(int.load(Ordering::Relaxed), idx as _)); }) });fn from_mut_slice(v: &mut [i32]) -> &mut [Self]Get atomic access to a
&mut [i32]slice.Note: This function is only available on targets where
AtomicI32has the same alignment asi32.Examples
#![feature(atomic_from_mut)] use std::sync::atomic::{AtomicI32, Ordering}; let mut some_ints = [0; 10]; let a = &*AtomicI32::from_mut_slice(&mut some_ints); std::thread::scope(|s| { for i in 0..a.len() { s.spawn(move || a[i].store(i as _, Ordering::Relaxed)); } }); for (i, n) in some_ints.into_iter().enumerate() { assert_eq!(i, n as usize); }const fn into_inner(self: Self) -> i32Consumes the atomic and returns the contained value.
This is safe because passing
selfby value guarantees that no other threads are concurrently accessing the atomic data.Examples
use AtomicI32; let some_var = new; assert_eq!;fn load(self: &Self, order: Ordering) -> i32Loads a value from the atomic integer.
loadtakes anOrderingargument which describes the memory ordering of this operation. Possible values areSeqCst,AcquireandRelaxed.Panics
Panics if
orderisReleaseorAcqRel.Examples
use ; let some_var = new; assert_eq!;fn store(self: &Self, val: i32, order: Ordering)Stores a value into the atomic integer.
storetakes anOrderingargument which describes the memory ordering of this operation. Possible values areSeqCst,ReleaseandRelaxed.Panics
Panics if
orderisAcquireorAcqRel.Examples
use ; let some_var = new; some_var.store; assert_eq!;fn swap(self: &Self, val: i32, order: Ordering) -> i32Stores a value into the atomic integer, returning the previous value.
swaptakes anOrderingargument which describes the memory ordering of this operation. All ordering modes are possible. Note that usingAcquiremakes the store part of this operationRelaxed, and usingReleasemakes the load partRelaxed.Note: This method is only available on platforms that support atomic operations on
i32.Examples
use ; let some_var = new; assert_eq!;fn compare_and_swap(self: &Self, current: i32, new: i32, order: Ordering) -> i32Stores a value into the atomic integer if the current value is the same as the
currentvalue.The return value is always the previous value. If it is equal to
current, then the value was updated.compare_and_swapalso takes anOrderingargument which describes the memory ordering of this operation. Notice that even when usingAcqRel, the operation might fail and hence just perform anAcquireload, but not haveReleasesemantics. UsingAcquiremakes the store part of this operationRelaxedif it happens, and usingReleasemakes the load partRelaxed.Note: This method is only available on platforms that support atomic operations on
i32.Migrating to
compare_exchangeandcompare_exchange_weakcompare_and_swapis 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 compare_and_swapandcompare_exchangealso differ in their return type. You can usecompare_exchange(...).unwrap_or_else(|x| x)to recover the behavior ofcompare_and_swap, but in most cases it is more idiomatic to check whether the return value isOkorErrrather than to infer success vs failure based on the value that was read.During migration, consider whether it makes sense to use
compare_exchange_weakinstead.compare_exchange_weakis allowed to fail spuriously even when the comparison succeeds, which allows the compiler to generate better assembly code when the compare and swap is used in a loop.Examples
use ; let some_var = new; assert_eq!; assert_eq!; assert_eq!; assert_eq!;fn compare_exchange(self: &Self, current: i32, new: i32, success: Ordering, failure: Ordering) -> Result<i32, i32>Stores a value into the atomic integer if the current value is the same as the
currentvalue.The return value is a result indicating whether the new value was written and containing the previous value. On success this value is guaranteed to be equal to
current.compare_exchangetakes twoOrderingarguments 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,AcquireorRelaxed.Note: This method is only available on platforms that support atomic operations on
i32.Examples
use ; let some_var = new; assert_eq!; assert_eq!; assert_eq!; assert_eq!;Considerations
compare_exchangeis a compare-and-swap operation and thus exhibits the usual downsides of CAS operations. In particular, a load of the value followed by a successfulcompare_exchangewith the previous load does not ensure that other threads have not changed the value in the interim! This is usually important when the equality check in thecompare_exchangeis being used to check the identity of a value, but equality does not necessarily imply identity. This is a particularly common case for pointers, as a pointer holding the same address does not imply that the same object exists at that address! In this case,compare_exchangecan lead to the ABA problem.fn compare_exchange_weak(self: &Self, current: i32, new: i32, success: Ordering, failure: Ordering) -> Result<i32, i32>Stores a value into the atomic integer if the current value is the same as the
currentvalue.Unlike
AtomicI32::compare_exchange, this function is allowed to spuriously fail even when the comparison succeeds, which can result in more efficient code on some platforms. The return value is a result indicating whether the new value was written and containing the previous value.compare_exchange_weaktakes twoOrderingarguments 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,AcquireorRelaxed.Note: This method is only available on platforms that support atomic operations on
i32.Examples
use ; let val = new; let mut old = val.load; loopConsiderations
compare_exchangeis a compare-and-swap operation and thus exhibits the usual downsides of CAS operations. In particular, a load of the value followed by a successfulcompare_exchangewith the previous load does not ensure that other threads have not changed the value in the interim. This is usually important when the equality check in thecompare_exchangeis being used to check the identity of a value, but equality does not necessarily imply identity. This is a particularly common case for pointers, as a pointer holding the same address does not imply that the same object exists at that address! In this case,compare_exchangecan lead to the ABA problem.fn fetch_add(self: &Self, val: i32, order: Ordering) -> i32Adds to the current value, returning the previous value.
This operation wraps around on overflow.
fetch_addtakes anOrderingargument which describes the memory ordering of this operation. All ordering modes are possible. Note that usingAcquiremakes the store part of this operationRelaxed, and usingReleasemakes the load partRelaxed.Note: This method is only available on platforms that support atomic operations on
i32.Examples
use ; let foo = new; assert_eq!; assert_eq!;fn fetch_sub(self: &Self, val: i32, order: Ordering) -> i32Subtracts from the current value, returning the previous value.
This operation wraps around on overflow.
fetch_subtakes anOrderingargument which describes the memory ordering of this operation. All ordering modes are possible. Note that usingAcquiremakes the store part of this operationRelaxed, and usingReleasemakes the load partRelaxed.Note: This method is only available on platforms that support atomic operations on
i32.Examples
use ; let foo = new; assert_eq!; assert_eq!;fn fetch_and(self: &Self, val: i32, order: Ordering) -> i32Bitwise "and" with the current value.
Performs a bitwise "and" operation on the current value and the argument
val, and sets the new value to the result.Returns the previous value.
fetch_andtakes anOrderingargument which describes the memory ordering of this operation. All ordering modes are possible. Note that usingAcquiremakes the store part of this operationRelaxed, and usingReleasemakes the load partRelaxed.Note: This method is only available on platforms that support atomic operations on
i32.Examples
use ; let foo = new; assert_eq!; assert_eq!;fn fetch_nand(self: &Self, val: i32, order: Ordering) -> i32Bitwise "nand" with the current value.
Performs a bitwise "nand" operation on the current value and the argument
val, and sets the new value to the result.Returns the previous value.
fetch_nandtakes anOrderingargument which describes the memory ordering of this operation. All ordering modes are possible. Note that usingAcquiremakes the store part of this operationRelaxed, and usingReleasemakes the load partRelaxed.Note: This method is only available on platforms that support atomic operations on
i32.Examples
use ; let foo = new; assert_eq!; assert_eq!;fn fetch_or(self: &Self, val: i32, order: Ordering) -> i32Bitwise "or" with the current value.
Performs a bitwise "or" operation on the current value and the argument
val, and sets the new value to the result.Returns the previous value.
fetch_ortakes anOrderingargument which describes the memory ordering of this operation. All ordering modes are possible. Note that usingAcquiremakes the store part of this operationRelaxed, and usingReleasemakes the load partRelaxed.Note: This method is only available on platforms that support atomic operations on
i32.Examples
use ; let foo = new; assert_eq!; assert_eq!;fn fetch_xor(self: &Self, val: i32, order: Ordering) -> i32Bitwise "xor" with the current value.
Performs a bitwise "xor" operation on the current value and the argument
val, and sets the new value to the result.Returns the previous value.
fetch_xortakes anOrderingargument which describes the memory ordering of this operation. All ordering modes are possible. Note that usingAcquiremakes the store part of this operationRelaxed, and usingReleasemakes the load partRelaxed.Note: This method is only available on platforms that support atomic operations on
i32.Examples
use ; let foo = new; assert_eq!; assert_eq!;fn fetch_update<F>(self: &Self, set_order: Ordering, fetch_order: Ordering, f: F) -> Result<i32, i32> where F: FnMut(i32) -> Option<i32>Fetches the value, and applies a function to it that returns an optional new value. Returns a
ResultofOk(previous_value)if the function returnedSome(_), elseErr(previous_value).Note: This may call the function multiple times if the value has been changed from 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 ofAtomicI32::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,AcquireorRelaxed.Note: This method is only available on platforms that support atomic operations on
i32.Considerations
This method is not magic; it is not provided by the hardware, and does not act like a critical section or mutex.
It is implemented on top of an atomic compare-and-swap operation, and thus is subject to the usual drawbacks of CAS operations. In particular, be careful of the ABA problem if this atomic integer is an index or more generally if knowledge of only the bitwise value of the atomic is not in and of itself sufficient to ensure any required preconditions.
Examples
use ; let x = new; assert_eq!; assert_eq!; assert_eq!; assert_eq!;fn try_update<impl FnMut(i32) -> Option<i32>: FnMut(i32) -> Option<i32>>(self: &Self, set_order: Ordering, fetch_order: Ordering, f: impl FnMut(i32) -> Option<i32>) -> Result<i32, i32>Fetches the value, and applies a function to it that returns an optional new value. Returns a
ResultofOk(previous_value)if the function returnedSome(_), elseErr(previous_value).See also:
update.Note: This may call the function multiple times if the value has been changed from 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.try_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 ofAtomicI32::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,AcquireorRelaxed.Note: This method is only available on platforms that support atomic operations on
i32.Considerations
This method is not magic; it is not provided by the hardware, and does not act like a critical section or mutex.
It is implemented on top of an atomic compare-and-swap operation, and thus is subject to the usual drawbacks of CAS operations. In particular, be careful of the ABA problem if this atomic integer is an index or more generally if knowledge of only the bitwise value of the atomic is not in and of itself sufficient to ensure any required preconditions.
Examples
use ; let x = new; assert_eq!; assert_eq!; assert_eq!; assert_eq!;fn update<impl FnMut(i32) -> i32: FnMut(i32) -> i32>(self: &Self, set_order: Ordering, fetch_order: Ordering, f: impl FnMut(i32) -> i32) -> i32Fetches the value, applies a function to it that it return a new value. The new value is stored and the old value is returned.
See also:
try_update.Note: This may call the function multiple times if the value has been changed from other threads in the meantime, but the function will have been applied only once to the stored value.
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 ofAtomicI32::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,AcquireorRelaxed.Note: This method is only available on platforms that support atomic operations on
i32.Considerations
This method is not magic; it is not provided by the hardware, and does not act like a critical section or mutex.
It is implemented on top of an atomic compare-and-swap operation, and thus is subject to the usual drawbacks of CAS operations. In particular, be careful of the ABA problem if this atomic integer is an index or more generally if knowledge of only the bitwise value of the atomic is not in and of itself sufficient to ensure any required preconditions.
Examples
use ; let x = new; assert_eq!; assert_eq!; assert_eq!;fn fetch_max(self: &Self, val: i32, order: Ordering) -> i32Maximum with the current value.
Finds the maximum of the current value and the argument
val, and sets the new value to the result.Returns the previous value.
fetch_maxtakes anOrderingargument which describes the memory ordering of this operation. All ordering modes are possible. Note that usingAcquiremakes the store part of this operationRelaxed, and usingReleasemakes the load partRelaxed.Note: This method is only available on platforms that support atomic operations on
i32.Examples
use ; let foo = new; assert_eq!; assert_eq!;If you want to obtain the maximum value in one step, you can use the following:
use ; let foo = new; let bar = 42; let max_foo = foo.fetch_max.max; assert!;fn fetch_min(self: &Self, val: i32, order: Ordering) -> i32Minimum with the current value.
Finds the minimum of the current value and the argument
val, and sets the new value to the result.Returns the previous value.
fetch_mintakes anOrderingargument which describes the memory ordering of this operation. All ordering modes are possible. Note that usingAcquiremakes the store part of this operationRelaxed, and usingReleasemakes the load partRelaxed.Note: This method is only available on platforms that support atomic operations on
i32.Examples
use ; let foo = new; assert_eq!; assert_eq!; assert_eq!; assert_eq!;If you want to obtain the minimum value in one step, you can use the following:
use ; let foo = new; let bar = 12; let min_foo = foo.fetch_min.min; assert_eq!;const fn as_ptr(self: &Self) -> *mut i32Returns a mutable pointer to the underlying integer.
Doing non-atomic reads and writes on the resulting integer can be a data race. This method is mostly useful for FFI, where the function signature may use
*mut i32instead of&AtomicI32.Returning an
*mutpointer from a shared reference to this atomic is safe because the atomic types work with interior mutability. All modifications of an atomic change the value through a shared reference, and can do so safely as long as they use atomic operations. Any use of the returned raw pointer requires anunsafeblock and still has to uphold the requirements of the memory model.Examples
# fn main() { use std::sync::atomic::AtomicI32; extern "C" { fn my_atomic_op(arg: *mut i32); } let atomic = AtomicI32::new(1); // SAFETY: Safe as long as `my_atomic_op` is atomic. unsafe { my_atomic_op(atomic.as_ptr()); } # }
impl Debug for AtomicI32
fn fmt(self: &Self, f: &mut fmt::Formatter<'_>) -> fmt::Result
impl Default for AtomicI32
fn default() -> Self
impl Freeze for AtomicI32
impl From for AtomicI32
fn from(v: i32) -> SelfConverts an
i32into anAtomicI32.
impl RefUnwindSafe for crate::sync::atomic::AtomicI32
impl Send for AtomicI32
impl Sync for AtomicI32
impl Unpin for AtomicI32
impl UnwindSafe for AtomicI32
impl<T> Any for AtomicI32
fn type_id(self: &Self) -> TypeId
impl<T> Borrow for AtomicI32
fn borrow(self: &Self) -> &T
impl<T> BorrowMut for AtomicI32
fn borrow_mut(self: &mut Self) -> &mut T
impl<T> From for AtomicI32
fn from(t: T) -> TReturns the argument unchanged.
impl<T, U> Into for AtomicI32
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 AtomicI32
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
impl<T, U> TryInto for AtomicI32
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>