Values that can be operated on atomically.
Atomic
supports all primitive types (integer types, pointers, bool), with the exception of
zero-sized types (e.g. void). Some types (e.g. u128 and i128) may not be available on all
platforms or require library support (libatomic
).
Example
use std::sync::{Atomic, Ordering};
let a: Atomic<i32> = Atomic::new(5);
assert_eq!(a.exchange(10, Ordering::Relaxed), 5);
assert_eq!(a.load(Ordering::Relaxed), 10);
Run this example
Methods
-
fn new(inner: T) -> Atomic<T>
Create a new
Atomic
value with the given initial value. -
fn from_mut_ptr(inner: &mut T) -> &mut Atomic<T>
Convert a pointer to a value into a
Atomic
pointer referencing the same memory.The pointed-to value needs to be sufficiently aligned for the target platform.
Example
use std::sync::{Atomic, Ordering}; let i = 42; let a = Atomic::from_mut_ptr(&i); assert_eq!(a.exchange(10, Ordering::Relaxed), 42); assert_eq!(i, 10);
Run this example -
fn from_mut_slice(inner: &mut [T]) -> &mut [Atomic<T>]
Convert a slice of values into a slice of
Atomic
values referencing the same memory.The pointed-to values need to be sufficiently aligned for the target platform.
Example
use std::sync::{Atomic, Ordering}; let arr = [1, 2, 3]; let a = Atomic::from_mut_slice(&arr); for i in a.iter_mut() { i.fetch_add(1, Ordering::Relaxed); } assert_eq!(arr[..], &[2, 3, 4]);
Run this example -
Loads a value from the atomic variable.
-
Stores a value into the atomic variable.
-
Stores a value into the atomic variable, atomically returning the old value.
-
fn compare_exchange(self: &mut Atomic<T>, expected: T, desired: T, success_ordering: Ordering, failure_ordering: Ordering) -> Result<T, T>
Atomically compares the value in the atomic variable to
expected
and, if they are equal, sets the atomic variable todesired
.This is the strong version, which will not fail spuriously. See also compare_exchange_weak.
Returns previous value as an
Result::ok(...)
variant if the value was updated and as anResult::err(...)
if it was not.Example
use std::sync::{Atomic, Ordering}; /// Atomic version of a square root using a CAS loop fn fetch_sqrt(val: &mut Atomic<u64>, ordering: Ordering) -> u64 { let old = val.load(Ordering::Relaxed); loop { let root = (old as f64).sqrt() as u64; let ret = val.compare_exchange(old, root, ordering, Ordering::Relaxed); if ret.is_ok() { return old; } else { old = ret.unwrap_err(); } } } let val = Atomic::new(144u64); assert_eq!(val.fetch_sqrt(Ordering::Relaxed), 144u64); assert_eq!(val.load(Ordering::Relaxed), 12u64);
Run this example -
fn compare_exchange_weak(self: &mut Atomic<T>, expected: T, desired: T, success_ordering: Ordering, failure_ordering: Ordering) -> Result<T, T>
Atomically compares the value in the atomic variable to
expected
and, if they are equal, sets the atomic variable todesired
.This is the weak version, which can fail spuriously even when the comparison succeeds.
Returns previous value as an
Result::ok(...)
variant if the value was updated and as anResult::err(...)
if it was not. -
fn fetch_update<F>(self: &mut Atomic<T>, set_order: Ordering, fetch_order: Ordering, f: F) -> Result<T, T>
F: Fn(T) -> Option<T>Updates the value of the atomic variable using a callback function.
The callback function is passed the current value of the variable and returns the desired value or
Option::none()
to leave the value unchanged.Returns previous value as an
Result::ok(...)
variant if the value was updated and as anResult::err(...)
if it was not.Example
use std::sync::{Atomic, Ordering::SeqCst}; // Simulate a Collatz sequence starting with 39 let val = Atomic::new(39); loop { let value = val.fetch_update(SeqCst, SeqCst, |v: i32| -> Option<i32> { if v == 1 { Option::none() } else if v % 2 == 0 { Option::some(v / 2) } else { Option::some(v * 3 + 1) } }); if value.is_ok() { println!("val = {}", value.unwrap()); } else { println!("val = {}. We are done.", value.unwrap_err()); break; } }
Run this example
impl Atomic<T> { ... }
T: Integer
-
Atomically adds
value
to the atomic variable and returns the old value. -
Atomically subtracts
value
from the atomic variable and returns the old value. -
Atomically performs
*self &= value
and returns the old value. -
Atomically performs
*self |= value
and returns the old value. -
Atomically performs
*self ^= value
and returns the old value. -
Atomically performs
*self = ~(*self & value)
and returns the old value.