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 Some(Ordering::Greater)
77 } else if self_cycle > max_cycle / 4 * 3 && other_cycle < max_cycle / 4 {
78 Some(Ordering::Less)
80 } else {
81 ord
82 }
83 }
84}