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