shuttle_std/sync/atomic/
bool.rs1use crate::sync::atomic::Atomic;
2#[cfg(test)]
3use crate::sync::ResourceSignature;
4use std::sync::atomic::Ordering;
5
6pub struct AtomicBool {
8 inner: Atomic<bool>,
9}
10
11impl Default for AtomicBool {
12 fn default() -> Self {
13 Self::new(Default::default())
14 }
15}
16
17impl From<bool> for AtomicBool {
18 fn from(b: bool) -> Self {
19 Self::new(b)
20 }
21}
22
23impl std::fmt::Debug for AtomicBool {
24 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
25 std::fmt::Debug::fmt(unsafe { &self.raw_load() }, f)
26 }
27}
28
29impl AtomicBool {
30 #[track_caller]
32 pub const fn new(v: bool) -> Self {
33 Self { inner: Atomic::new(v) }
34 }
35
36 pub fn get_mut(&mut self) -> &mut bool {
38 self.inner.get_mut()
39 }
40
41 pub fn into_inner(self) -> bool {
43 self.inner.into_inner()
44 }
45
46 pub fn load(&self, order: Ordering) -> bool {
48 self.inner.load(order)
49 }
50
51 pub fn store(&self, val: bool, order: Ordering) {
53 self.inner.store(val, order)
54 }
55
56 pub fn swap(&self, val: bool, order: Ordering) -> bool {
58 self.inner.swap(val, order)
59 }
60
61 pub fn try_update(
65 &self,
66 set_order: Ordering,
67 fetch_order: Ordering,
68 mut f: impl FnMut(bool) -> Option<bool>,
69 ) -> Result<bool, bool> {
70 let mut prev = self.load(fetch_order);
71 while let Some(next) = f(prev) {
72 match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
73 x @ Ok(_) => return x,
74 Err(next_prev) => prev = next_prev,
75 }
76 }
77 Err(prev)
78 }
79
80 pub fn fetch_update<F>(&self, set_order: Ordering, fetch_order: Ordering, f: F) -> Result<bool, bool>
85 where
86 F: FnMut(bool) -> Option<bool>,
87 {
88 self.try_update(set_order, fetch_order, f)
89 }
90
91 pub fn update(&self, set_order: Ordering, fetch_order: Ordering, mut f: impl FnMut(bool) -> bool) -> bool {
94 let mut prev = self.load(fetch_order);
95 loop {
96 match self.compare_exchange_weak(prev, f(prev), set_order, fetch_order) {
97 Ok(x) => break x,
98 Err(next_prev) => prev = next_prev,
99 }
100 }
101 }
102
103 #[deprecated(since = "0.0.6", note = "Use `compare_exchange` or `compare_exchange_weak` instead")]
106 pub fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> bool {
107 match self.compare_exchange(current, new, order, order) {
108 Ok(v) => v,
109 Err(v) => v,
110 }
111 }
112
113 pub fn compare_exchange(
120 &self,
121 current: bool,
122 new: bool,
123 success: Ordering,
124 failure: Ordering,
125 ) -> Result<bool, bool> {
126 self.inner
127 .try_update(success, failure, |val| (val == current).then_some(new))
128 }
129
130 pub fn compare_exchange_weak(
139 &self,
140 current: bool,
141 new: bool,
142 success: Ordering,
143 failure: Ordering,
144 ) -> Result<bool, bool> {
145 self.compare_exchange(current, new, success, failure)
146 }
147
148 pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
150 self.inner.try_update(order, order, |old| Some(old & val)).unwrap()
151 }
152
153 pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
155 self.inner.try_update(order, order, |old| Some(!(old & val))).unwrap()
156 }
157
158 pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
160 self.inner.try_update(order, order, |old| Some(old | val)).unwrap()
161 }
162
163 pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
165 self.inner.try_update(order, order, |old| Some(old ^ val)).unwrap()
166 }
167
168 pub fn fetch_not(&self, order: Ordering) -> bool {
170 self.fetch_xor(true, order)
171 }
172
173 pub unsafe fn raw_load(&self) -> bool {
181 self.inner.raw_load()
182 }
183
184 #[cfg(test)]
185 pub(crate) fn signature(&self) -> ResourceSignature {
186 self.inner.signature()
187 }
188}