Struct AtomicI64
struct AtomicI64 { ... }
An integer type which can be safely shared between threads.
This type has the same in-memory representation as the underlying integer type,
i64.
If the compiler and the platform support atomic loads and stores of i64, this type is a wrapper for the standard library's AtomicI64. If the platform supports it but the compiler does not, atomic operations are implemented using
inline assembly. Otherwise synchronizes using global locks.
You can call [AtomicI64::is_lock_free()] to check whether
atomic instructions or locks will be used.
Implementations
impl AtomicI64
const fn new(v: i64) -> SelfCreates a new atomic integer.
Examples
use AtomicI64; let atomic_forty_two = new;unsafe const fn from_ptr<'a>(ptr: *mut i64) -> &'a SelfCreates a new reference to an atomic integer from a pointer.
This is
const fnon Rust 1.83+.Safety
ptrmust be aligned toalign_of::<AtomicI64>()(note that on some platforms this can be bigger thanalign_of::<i64>()).ptrmust be valid for both reads and writes for the whole lifetime'a.- If this atomic type is lock-free, non-atomic accesses to the value
behind
ptrmust have a happens-before relationship with atomic accesses via the returned value (or vice-versa).- In other words, time periods where the value is accessed atomically may not overlap with periods where the value is accessed non-atomically.
- This requirement is trivially satisfied if
ptris never used non-atomically for the duration of lifetime'a. Most use cases should be able to follow this guideline. - This requirement is also trivially satisfied if all accesses (atomic or not) are done from the same thread.
- If this atomic type is not lock-free:
- Any accesses to the value behind
ptrmust have a happens-before relationship with accesses via the returned value (or vice-versa). - Any concurrent accesses to the value behind
ptrfor the duration of lifetime'amust be compatible with operations performed by this atomic type.
- Any accesses to the value behind
- This method must not be used to create overlapping or mixed-size atomic accesses, as these are not supported by the memory model.
fn is_lock_free() -> boolReturns
trueif operations on values of this type are lock-free.If the compiler or the platform doesn't support the necessary atomic instructions, global locks for every potentially concurrent atomic operation will be used.
Examples
use AtomicI64; let is_lock_free = is_lock_free;const fn is_always_lock_free() -> boolReturns
trueif operations on values of this type are lock-free.If the compiler or the platform doesn't support the necessary atomic instructions, global locks for every potentially concurrent atomic operation will be used.
Note: If the atomic operation relies on dynamic CPU feature detection, this type may be lock-free even if the function returns false.
Examples
use AtomicI64; const IS_ALWAYS_LOCK_FREE: bool = is_always_lock_free;const fn get_mut(self: &mut Self) -> &mut i64Returns 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.
This is
const fnon Rust 1.83+.Examples
use ; let mut some_var = new; assert_eq!; *some_var.get_mut = 5; assert_eq!;const fn into_inner(self: Self) -> i64Consumes 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.This is
const fnon Rust 1.56+.Examples
use AtomicI64; let some_var = new; assert_eq!;fn load(self: &Self, order: Ordering) -> i64Loads 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: i64, 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: i64, order: Ordering) -> i64Stores 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.Examples
use ; let some_var = new; assert_eq!;fn compare_exchange(self: &Self, current: i64, new: i64, success: Ordering, failure: Ordering) -> Result<i64, i64>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.Panics
Panics if
failureisRelease,AcqRel.Examples
use ; let some_var = new; assert_eq!; assert_eq!; assert_eq!; assert_eq!;fn compare_exchange_weak(self: &Self, current: i64, new: i64, success: Ordering, failure: Ordering) -> Result<i64, i64>Stores a value into the atomic integer if the current value is the same as the
currentvalue. Unlikecompare_exchangethis 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.Panics
Panics if
failureisRelease,AcqRel.Examples
use ; let val = new; let mut old = val.load; loopfn fetch_add(self: &Self, val: i64, order: Ordering) -> i64Adds 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.Examples
use ; let foo = new; assert_eq!; assert_eq!;fn add(self: &Self, val: i64, order: Ordering)Adds to the current value.
This operation wraps around on overflow.
Unlike
fetch_add, this does not return the previous value.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.This function may generate more efficient code than
fetch_addon some platforms.- MSP430:
addinstead of disabling interrupts ({8,16}-bit atomics)
Examples
use ; let foo = new; foo.add; assert_eq!;- MSP430:
fn fetch_sub(self: &Self, val: i64, order: Ordering) -> i64Subtracts 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.Examples
use ; let foo = new; assert_eq!; assert_eq!;fn sub(self: &Self, val: i64, order: Ordering)Subtracts from the current value.
This operation wraps around on overflow.
Unlike
fetch_sub, this does not return the previous value.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.This function may generate more efficient code than
fetch_subon some platforms.- MSP430:
subinstead of disabling interrupts ({8,16}-bit atomics)
Examples
use ; let foo = new; foo.sub; assert_eq!;- MSP430:
fn fetch_and(self: &Self, val: i64, order: Ordering) -> i64Bitwise "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.Examples
use ; let foo = new; assert_eq!; assert_eq!;fn and(self: &Self, val: i64, order: Ordering)Bitwise "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.Unlike
fetch_and, this does not return the previous value.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.This function may generate more efficient code than
fetch_andon some platforms.- x86/x86_64:
lock andinstead ofcmpxchgloop ({8,16,32}-bit atomics on x86, but additionally 64-bit atomics on x86_64) - MSP430:
andinstead of disabling interrupts ({8,16}-bit atomics)
Note: On x86/x86_64, the use of either function should not usually affect the generated code, because LLVM can properly optimize the case where the result is unused.
Examples
use ; let foo = new; assert_eq!; assert_eq!;- x86/x86_64:
fn fetch_nand(self: &Self, val: i64, order: Ordering) -> i64Bitwise "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.Examples
use ; let foo = new; assert_eq!; assert_eq!;fn fetch_or(self: &Self, val: i64, order: Ordering) -> i64Bitwise "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.Examples
use ; let foo = new; assert_eq!; assert_eq!;fn or(self: &Self, val: i64, order: Ordering)Bitwise "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.Unlike
fetch_or, this does not return the previous value.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.This function may generate more efficient code than
fetch_oron some platforms.- x86/x86_64:
lock orinstead ofcmpxchgloop ({8,16,32}-bit atomics on x86, but additionally 64-bit atomics on x86_64) - MSP430:
orinstead of disabling interrupts ({8,16}-bit atomics)
Note: On x86/x86_64, the use of either function should not usually affect the generated code, because LLVM can properly optimize the case where the result is unused.
Examples
use ; let foo = new; assert_eq!; assert_eq!;- x86/x86_64:
fn fetch_xor(self: &Self, val: i64, order: Ordering) -> i64Bitwise "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.Examples
use ; let foo = new; assert_eq!; assert_eq!;fn xor(self: &Self, val: i64, order: Ordering)Bitwise "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.Unlike
fetch_xor, this does not return the previous value.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.This function may generate more efficient code than
fetch_xoron some platforms.- x86/x86_64:
lock xorinstead ofcmpxchgloop ({8,16,32}-bit atomics on x86, but additionally 64-bit atomics on x86_64) - MSP430:
xorinstead of disabling interrupts ({8,16}-bit atomics)
Note: On x86/x86_64, the use of either function should not usually affect the generated code, because LLVM can properly optimize the case where the result is unused.
Examples
use ; let foo = new; foo.xor; assert_eq!;- x86/x86_64:
fn fetch_update<F>(self: &Self, set_order: Ordering, fetch_order: Ordering, f: F) -> Result<i64, i64> where F: FnMut(i64) -> Option<i64>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 ofcompare_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.Panics
Panics if
fetch_orderisRelease,AcqRel.Considerations
This method is not magic; it is not provided by the hardware. It is implemented in terms of
compare_exchange_weak, and suffers from the same drawbacks. In particular, this method will not circumvent the ABA Problem.Examples
use ; let x = new; assert_eq!; assert_eq!; assert_eq!; assert_eq!;fn fetch_max(self: &Self, val: i64, order: Ordering) -> i64Maximum 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.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: i64, order: Ordering) -> i64Minimum 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.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!;fn bit_set(self: &Self, bit: u32, order: Ordering) -> boolSets the bit at the specified bit-position to 1.
Returns
trueif the specified bit was previously set to 1.bit_settakes 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.This corresponds to x86's
lock bts, and the implementation calls them on x86/x86_64.Examples
use ; let foo = new; assert!; assert_eq!; assert!; assert_eq!;fn bit_clear(self: &Self, bit: u32, order: Ordering) -> boolClears the bit at the specified bit-position to 1.
Returns
trueif the specified bit was previously set to 1.bit_cleartakes 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.This corresponds to x86's
lock btr, and the implementation calls them on x86/x86_64.Examples
use ; let foo = new; assert!; assert_eq!;fn bit_toggle(self: &Self, bit: u32, order: Ordering) -> boolToggles the bit at the specified bit-position.
Returns
trueif the specified bit was previously set to 1.bit_toggletakes 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.This corresponds to x86's
lock btc, and the implementation calls them on x86/x86_64.Examples
use ; let foo = new; assert!; assert_eq!; assert!; assert_eq!;fn fetch_not(self: &Self, order: Ordering) -> i64Logical negates the current value, and sets the new value to the result.
Returns the previous value.
fetch_nottakes 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.Examples
use ; let foo = new; assert_eq!; assert_eq!;fn not(self: &Self, order: Ordering)Logical negates the current value, and sets the new value to the result.
Unlike
fetch_not, this does not return the previous value.nottakes 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.This function may generate more efficient code than
fetch_noton some platforms.- x86/x86_64:
lock notinstead ofcmpxchgloop ({8,16,32}-bit atomics on x86, but additionally 64-bit atomics on x86_64) - MSP430:
invinstead of disabling interrupts ({8,16}-bit atomics)
Examples
use ; let foo = new; foo.not; assert_eq!;- x86/x86_64:
fn fetch_neg(self: &Self, order: Ordering) -> i64Negates the current value, and sets the new value to the result.
Returns the previous value.
fetch_negtakes 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.Examples
use ; let foo = new; assert_eq!; assert_eq!; assert_eq!; assert_eq!;fn neg(self: &Self, order: Ordering)Negates the current value, and sets the new value to the result.
Unlike
fetch_neg, this does not return the previous value.negtakes 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.This function may generate more efficient code than
fetch_negon some platforms.- x86/x86_64:
lock neginstead ofcmpxchgloop ({8,16,32}-bit atomics on x86, but additionally 64-bit atomics on x86_64)
Examples
use ; let foo = new; foo.neg; assert_eq!; foo.neg; assert_eq!;- x86/x86_64:
const fn as_ptr(self: &Self) -> *mut i64Returns a mutable pointer to the underlying integer.
Returning an
*mutpointer from a shared reference to this atomic is safe because the atomic types work with interior mutability. Any use of the returned raw pointer requires anunsafeblock and has to uphold the safety requirements. If there is concurrent access, note the following additional safety requirements:- If this atomic type is lock-free, any concurrent operations on it must be atomic.
- Otherwise, any concurrent operations on it must be compatible with operations performed by this atomic type.
This is
const fnon Rust 1.58+.
impl Debug for AtomicI64
fn fmt(self: &Self, f: &mut Formatter<'_>) -> Result
impl Default for AtomicI64
fn default() -> Self
impl Freeze for AtomicI64
impl From for AtomicI64
fn from(v: i64) -> Self
impl RefUnwindSafe for AtomicI64
impl Send for AtomicI64
impl Sync for AtomicI64
impl Unpin for AtomicI64
impl UnsafeUnpin for AtomicI64
impl UnwindSafe for AtomicI64
impl<T> Any for AtomicI64
fn type_id(self: &Self) -> TypeId
impl<T> Borrow for AtomicI64
fn borrow(self: &Self) -> &T
impl<T> BorrowMut for AtomicI64
fn borrow_mut(self: &mut Self) -> &mut T
impl<T> From for AtomicI64
fn from(t: T) -> TReturns the argument unchanged.
impl<T, U> Into for AtomicI64
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 AtomicI64
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
impl<T, U> TryInto for AtomicI64
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>