#[cfg(loom)]
#[allow(unused_imports)]
pub(crate) use loom::sync::atomic::{AtomicBool, AtomicU64, AtomicU8, Ordering};
#[cfg(not(loom))]
#[allow(unused_imports)]
pub(crate) use std::sync::atomic::{AtomicBool, AtomicU64, AtomicU8, Ordering};
#[derive(Debug, Default)]
pub struct OrderedAtomicFlag(AtomicBool);
impl OrderedAtomicFlag {
pub fn reset(&self) {
self.0.store(false, Ordering::Release);
}
pub fn set(&self) {
self.0.store(true, Ordering::Release);
}
pub fn check_and_reset(&self) -> bool {
self.0
.compare_exchange(true, false, Ordering::AcqRel, Ordering::Relaxed)
.is_ok()
}
pub fn peek(&self) -> bool {
self.0.load(Ordering::Relaxed)
}
pub fn load(&self) -> bool {
self.0.load(Ordering::Acquire)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SwitchAtomicStateOk<T> {
Accepted {
previous_state: T,
},
Ignored,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SwitchAtomicStateErr<T> {
Rejected { current_state: T },
}
pub type SwitchAtomicStateResult<T> = Result<SwitchAtomicStateOk<T>, SwitchAtomicStateErr<T>>;
pub trait AtomicState {
type State: Copy;
fn peek(&self) -> Self::State;
fn load(&self) -> Self::State;
fn switch_to_desired(&self, desired_state: Self::State) -> SwitchAtomicStateOk<Self::State>;
fn switch_from_expected_to_desired(
&self,
expected_state: Self::State,
desired_state: Self::State,
) -> SwitchAtomicStateResult<Self::State>;
}