ach_util/
ring.rs

1use super::state::MemoryState;
2use core::cmp::Ordering;
3
4pub type AtomicMemoryRing = atomic::Atomic<MemoryRing>;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub struct MemoryRing(u32);
8impl MemoryRing {
9    pub const INIT: Self = Self::new(0, MemoryState::Uninitialized);
10    pub const fn new(cycle: usize, state: MemoryState) -> Self {
11        let cycle = cycle & 0x00FF_FFFF;
12        Self((state as u32) << 24 | cycle as u32)
13    }
14    pub const fn max_cycle() -> usize {
15        0x00FF_FFFF + 1
16    }
17    pub fn cycle(&self) -> usize {
18        (self.0 as usize) & 0x00FF_FFFF
19    }
20    pub fn set_cycle(&mut self, val: usize) {
21        let val = val & 0x00FF_FFFF;
22        self.0 = (self.0 & 0xFF00_0000) | val as u32;
23    }
24    pub fn state(&self) -> MemoryState {
25        ((self.0 >> 24) as u8).into()
26    }
27    pub fn set_state(&mut self, val: MemoryState) {
28        self.0 = (self.0 & 0x00FF_FFFF) | ((u8::from(val) as u32) << 24);
29    }
30    pub fn next(&self) -> Self {
31        let mut ret = *self;
32        match self.state() {
33            MemoryState::Uninitialized => ret.set_state(MemoryState::Initializing),
34            MemoryState::Initializing => ret.set_state(MemoryState::Initialized),
35            MemoryState::Initialized => ret.set_state(MemoryState::Erasing),
36            MemoryState::Erasing => {
37                let cycle = self.cycle() + 1;
38                ret.set_cycle(if cycle >= Self::max_cycle() { 0 } else { cycle });
39                ret.set_state(MemoryState::Uninitialized);
40            }
41            _ => unreachable!(),
42        }
43        ret
44    }
45
46    pub const fn max_idx(size: usize) -> usize {
47        let cycle_max = Self::max_cycle();
48        usize::MAX / size / cycle_max * size * cycle_max
49    }
50    pub const fn cycle_of_idx(idx: usize, size: usize) -> usize {
51        idx / size
52    }
53}
54impl From<u32> for MemoryRing {
55    fn from(s: u32) -> Self {
56        Self(s)
57    }
58}
59impl From<MemoryRing> for u32 {
60    fn from(s: MemoryRing) -> Self {
61        s.0
62    }
63}
64impl PartialOrd for MemoryRing {
65    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
66        let self_cycle = self.cycle();
67        let other_cycle = other.cycle();
68        let max_cycle = Self::max_cycle();
69        let ord = self_cycle.partial_cmp(&other_cycle);
70        if ord == Some(Ordering::Equal) {
71            self.state().partial_cmp(&other.state())
72        } else {
73            if self_cycle < max_cycle / 4 && other_cycle > max_cycle / 4 * 3 {
74                // self overflow
75                Some(Ordering::Greater)
76            } else if self_cycle > max_cycle / 4 * 3 && other_cycle < max_cycle / 4 {
77                // other overflow
78                Some(Ordering::Less)
79            } else {
80                ord
81            }
82        }
83    }
84}