Skip to main content

ach_util/
ring.rs

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