1use super::state::MemoryState;
2
3pub type AtomicMemoryRefer = atomic::Atomic<MemoryRefer>;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
6pub struct MemoryRefer(u32);
7impl Default for MemoryRefer {
8 fn default() -> Self {
9 Self::new()
10 }
11}
12impl MemoryRefer {
13 pub const fn new() -> Self {
15 Self(0)
16 }
17 pub fn state(&self) -> MemoryState {
18 ((self.0 >> 24) as u8).into()
19 }
20 pub fn set_state(&mut self, val: MemoryState) {
21 self.0 = (self.0 & 0x00FF_FFFF) | ((u8::from(val) as u32) << 24);
22 }
23 pub const fn max_refer() -> usize {
24 0x00FF_FFFF
25 }
26 pub fn ref_num(&self) -> Result<usize, MemoryState> {
27 let state = self.state();
28 if state.is_initialized() || state.is_regaining() || state.is_erasing() {
29 Ok((self.0 as usize) & 0x00FF_FFFF)
30 } else {
31 Err(state)
32 }
33 }
34 pub fn ref_add(&mut self) -> Result<(), MemoryState> {
35 let ref_num = self.ref_num()?;
36 if ref_num == Self::max_refer() {
37 return Ok(());
38 }
39 let state = self.state();
40 if state.is_initialized() {
41 self.0 += 1;
42 Ok(())
43 } else {
44 Err(state)
45 }
46 }
47 pub fn ref_sub(&mut self) -> Result<(), MemoryState> {
48 let ref_num = self.ref_num()?;
49 if ref_num == Self::max_refer() || ref_num == 0 {
50 return Ok(());
51 }
52 let state = self.state();
53 if state.is_initialized() || state.is_regaining() {
54 self.0 -= 1;
55 Ok(())
56 } else {
57 Err(state)
58 }
59 }
60}
61impl From<MemoryState> for MemoryRefer {
62 fn from(s: MemoryState) -> Self {
63 let mut refer = MemoryRefer::new();
64 refer.set_state(s);
65 refer
66 }
67}
68impl From<u32> for MemoryRefer {
69 fn from(s: u32) -> Self {
70 Self(s)
71 }
72}
73impl From<MemoryRefer> for u32 {
74 fn from(s: MemoryRefer) -> Self {
75 s.0
76 }
77}