1 use super::AtomicU64;
2 use crate::loom::sync::{atomic::Ordering, Mutex};
3 use crate::util::once_cell::OnceCell;
4 
5 pub(crate) struct StaticAtomicU64 {
6     init: u64,
7     cell: OnceCell<Mutex<u64>>,
8 }
9 
10 impl AtomicU64 {
new(val: u64) -> Self11     pub(crate) fn new(val: u64) -> Self {
12         Self {
13             inner: Mutex::new(val),
14         }
15     }
16 }
17 
18 impl StaticAtomicU64 {
new(val: u64) -> StaticAtomicU6419     pub(crate) const fn new(val: u64) -> StaticAtomicU64 {
20         StaticAtomicU64 {
21             init: val,
22             cell: OnceCell::new(),
23         }
24     }
25 
load(&self, order: Ordering) -> u6426     pub(crate) fn load(&self, order: Ordering) -> u64 {
27         *self.inner().lock()
28     }
29 
fetch_add(&self, val: u64, order: Ordering) -> u6430     pub(crate) fn fetch_add(&self, val: u64, order: Ordering) -> u64 {
31         let mut lock = self.inner().lock();
32         let prev = *lock;
33         *lock = prev + val;
34         prev
35     }
36 
compare_exchange_weak( &self, current: u64, new: u64, _success: Ordering, _failure: Ordering, ) -> Result<u64, u64>37     pub(crate) fn compare_exchange_weak(
38         &self,
39         current: u64,
40         new: u64,
41         _success: Ordering,
42         _failure: Ordering,
43     ) -> Result<u64, u64> {
44         let mut lock = self.inner().lock();
45 
46         if *lock == current {
47             *lock = new;
48             Ok(current)
49         } else {
50             Err(*lock)
51         }
52     }
53 
inner(&self) -> &Mutex<u64>54     fn inner(&self) -> &Mutex<u64> {
55         self.cell.get(|| Mutex::new(self.init))
56     }
57 }
58