Struct AtomicBool
struct AtomicBool { ... }
A boolean type which can be safely shared between threads.
This type has the same size, alignment, and bit validity as a bool.
Note: This type is only available on platforms that support atomic
loads and stores of u8.
Implementations
impl AtomicBool
const fn new(v: bool) -> AtomicBoolCreates a new
AtomicBool.Examples
use AtomicBool; let atomic_true = new; let atomic_false = new;unsafe const fn from_ptr<'a>(ptr: *mut bool) -> &'a AtomicBoolCreates a new
AtomicBoolfrom a pointer.Examples
use ; // Get a pointer to an allocated value let ptr: *mut bool = 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::<AtomicBool>()(note that this is always true, sincealign_of::<AtomicBool>() == 1).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 boolReturns a mutable reference to the underlying
bool.This is safe because the mutable reference guarantees that no other threads are concurrently accessing the atomic data.
Examples
use ; let mut some_bool = new; assert_eq!; *some_bool.get_mut = false; assert_eq!;fn from_mut(v: &mut bool) -> &mut SelfGets atomic access to a
&mut bool.Examples
use ; let mut some_bool = true; let a = from_mut; a.store; assert_eq!;fn get_mut_slice(this: &mut [Self]) -> &mut [bool]Gets non-atomic access to a
&mut [AtomicBool]slice.This 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::{AtomicBool, Ordering}; let mut some_bools = [const { AtomicBool::new(false) }; 10]; let view: &mut [bool] = AtomicBool::get_mut_slice(&mut some_bools); assert_eq!(view, [false; 10]); view[..5].copy_from_slice(&[true; 5]); std::thread::scope(|s| { for t in &some_bools[..5] { s.spawn(move || assert_eq!(t.load(Ordering::Relaxed), true)); } for f in &some_bools[5..] { s.spawn(move || assert_eq!(f.load(Ordering::Relaxed), false)); } });fn from_mut_slice(v: &mut [bool]) -> &mut [Self]Gets atomic access to a
&mut [bool]slice.Examples
use ; let mut some_bools = ; let a = &*from_mut_slice; scope; assert_eq!;const fn into_inner(self: Self) -> boolConsumes 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 AtomicBool; let some_bool = new; assert_eq!;fn load(self: &Self, order: Ordering) -> boolLoads a value from the bool.
loadtakes anOrderingargument which describes the memory ordering of this operation. Possible values areSeqCst,AcquireandRelaxed.Panics
Panics if
orderisReleaseorAcqRel.Examples
use ; let some_bool = new; assert_eq!;fn store(self: &Self, val: bool, order: Ordering)Stores a value into the bool.
storetakes anOrderingargument which describes the memory ordering of this operation. Possible values areSeqCst,ReleaseandRelaxed.Panics
Panics if
orderisAcquireorAcqRel.Examples
use ; let some_bool = new; some_bool.store; assert_eq!;fn swap(self: &Self, val: bool, order: Ordering) -> boolStores a value into the bool, 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
u8.Examples
use ; let some_bool = new; assert_eq!; assert_eq!;fn compare_and_swap(self: &Self, current: bool, new: bool, order: Ordering) -> boolStores a value into the
boolif the current value is the same as thecurrentvalue.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
u8.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_bool = new; assert_eq!; assert_eq!; assert_eq!; assert_eq!;fn compare_exchange(self: &Self, current: bool, new: bool, success: Ordering, failure: Ordering) -> Result<bool, bool>Stores a value into the
boolif the current value is the same as thecurrentvalue.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
u8.Examples
use ; let some_bool = 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. In this case,compare_exchangecan lead to the ABA problem.fn compare_exchange_weak(self: &Self, current: bool, new: bool, success: Ordering, failure: Ordering) -> Result<bool, bool>Stores a value into the
boolif the current value is the same as thecurrentvalue.Unlike
AtomicBool::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
u8.Examples
use ; let val = new; let new = true; 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. In this case,compare_exchangecan lead to the ABA problem.fn fetch_and(self: &Self, val: bool, order: Ordering) -> boolLogical "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.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
u8.Examples
use ; let foo = new; assert_eq!; assert_eq!; let foo = new; assert_eq!; assert_eq!; let foo = new; assert_eq!; assert_eq!;fn fetch_nand(self: &Self, val: bool, order: Ordering) -> boolLogical "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.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
u8.Examples
use ; let foo = new; assert_eq!; assert_eq!; let foo = new; assert_eq!; assert_eq!; assert_eq!; let foo = new; assert_eq!; assert_eq!;fn fetch_or(self: &Self, val: bool, order: Ordering) -> boolLogical "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.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
u8.Examples
use ; let foo = new; assert_eq!; assert_eq!; let foo = new; assert_eq!; assert_eq!; let foo = new; assert_eq!; assert_eq!;fn fetch_xor(self: &Self, val: bool, order: Ordering) -> boolLogical "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.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
u8.Examples
use ; let foo = new; assert_eq!; assert_eq!; let foo = new; assert_eq!; assert_eq!; let foo = new; assert_eq!; assert_eq!;fn fetch_not(self: &Self, order: Ordering) -> boolLogical "not" with a boolean value.
Performs a logical "not" operation on 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.Note: This method is only available on platforms that support atomic operations on
u8.Examples
use ; let foo = new; assert_eq!; assert_eq!; let foo = new; assert_eq!; assert_eq!;const fn as_ptr(self: &Self) -> *mut boolReturns a mutable pointer to the underlying
bool.Doing non-atomic reads and writes on the resulting boolean can be a data race. This method is mostly useful for FFI, where the function signature may use
*mut boolinstead of&AtomicBool.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::AtomicBool; extern "C" { fn my_atomic_op(arg: *mut bool); } let mut atomic = AtomicBool::new(true); unsafe { my_atomic_op(atomic.as_ptr()); } # }fn fetch_update<F>(self: &Self, set_order: Ordering, fetch_order: Ordering, f: F) -> Result<bool, bool> where F: FnMut(bool) -> Option<bool>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 ofAtomicBool::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
u8.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.
Examples
use ; let x = new; assert_eq!; assert_eq!; assert_eq!; assert_eq!;fn try_update<impl FnMut(bool) -> Option<bool>: FnMut(bool) -> Option<bool>>(self: &Self, set_order: Ordering, fetch_order: Ordering, f: impl FnMut(bool) -> Option<bool>) -> Result<bool, bool>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 ofAtomicBool::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
u8.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.
Examples
use ; let x = new; assert_eq!; assert_eq!; assert_eq!; assert_eq!;fn update<impl FnMut(bool) -> bool: FnMut(bool) -> bool>(self: &Self, set_order: Ordering, fetch_order: Ordering, f: impl FnMut(bool) -> bool) -> boolFetches 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 ofAtomicBool::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
u8.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.
Examples
use ; let x = new; assert_eq!; assert_eq!; assert_eq!;
impl Debug for AtomicBool
fn fmt(self: &Self, f: &mut fmt::Formatter<'_>) -> fmt::Result
impl Default for AtomicBool
fn default() -> SelfCreates an
AtomicBoolinitialized tofalse.
impl Freeze for AtomicBool
impl From for AtomicBool
fn from(b: bool) -> SelfConverts a
boolinto anAtomicBool.Examples
use AtomicBool; let atomic_bool = from; assert_eq!
impl RefUnwindSafe for crate::sync::atomic::AtomicBool
impl Send for AtomicBool
impl Sync for AtomicBool
impl Unpin for AtomicBool
impl UnwindSafe for AtomicBool
impl<T> Any for AtomicBool
fn type_id(self: &Self) -> TypeId
impl<T> Borrow for AtomicBool
fn borrow(self: &Self) -> &T
impl<T> BorrowMut for AtomicBool
fn borrow_mut(self: &mut Self) -> &mut T
impl<T> From for AtomicBool
fn from(t: T) -> TReturns the argument unchanged.
impl<T, U> Into for AtomicBool
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 AtomicBool
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
impl<T, U> TryInto for AtomicBool
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>