1#[cfg(loom)]
2#[allow(unused_imports)]
3pub(crate) use loom::sync::atomic::{AtomicBool, AtomicU64, AtomicU8, Ordering};
4
5#[cfg(not(loom))]
6#[allow(unused_imports)]
7pub(crate) use std::sync::atomic::{AtomicBool, AtomicU64, AtomicU8, Ordering};
8
9#[derive(Debug, Default)]
14pub struct OrderedAtomicFlag(AtomicBool);
15
16impl OrderedAtomicFlag {
17 pub fn reset(&self) {
18 self.0.store(false, Ordering::Release);
19 }
20
21 pub fn set(&self) {
22 self.0.store(true, Ordering::Release);
23 }
24
25 pub fn check_and_reset(&self) -> bool {
26 self.0
30 .compare_exchange(true, false, Ordering::AcqRel, Ordering::Relaxed)
31 .is_ok()
32 }
33
34 pub fn peek(&self) -> bool {
35 self.0.load(Ordering::Relaxed)
36 }
37
38 pub fn load(&self) -> bool {
39 self.0.load(Ordering::Acquire)
40 }
41}
42
43#[derive(Debug, Clone, Copy, PartialEq, Eq)]
45pub enum SwitchAtomicStateOk<T> {
46 Accepted {
47 previous_state: T,
48 },
49
50 Ignored,
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq)]
55pub enum SwitchAtomicStateErr<T> {
56 Rejected { current_state: T },
57}
58
59pub type SwitchAtomicStateResult<T> = Result<SwitchAtomicStateOk<T>, SwitchAtomicStateErr<T>>;
60
61pub trait AtomicState {
65 type State: Copy;
66
67 fn peek(&self) -> Self::State;
71
72 fn load(&self) -> Self::State;
77
78 fn switch_to_desired(&self, desired_state: Self::State) -> SwitchAtomicStateOk<Self::State>;
83
84 fn switch_from_expected_to_desired(
90 &self,
91 expected_state: Self::State,
92 desired_state: Self::State,
93 ) -> SwitchAtomicStateResult<Self::State>;
94}