1use crate::sync::{AtomicU32, Ordering};
2
3#[repr(u32)]
5#[derive(Clone, Copy, Debug, PartialEq, Eq)]
6pub enum SlotState {
7 Free = 0,
8 Allocated = 1,
9 InFlight = 2,
10}
11
12impl SlotState {
13 #[inline]
14 pub fn from_u32(v: u32) -> Option<Self> {
15 match v {
16 0 => Some(SlotState::Free),
17 1 => Some(SlotState::Allocated),
18 2 => Some(SlotState::InFlight),
19 _ => None,
20 }
21 }
22}
23
24#[repr(C)]
26pub struct SlotMeta {
27 pub generation: AtomicU32,
28 pub state: AtomicU32,
29}
30
31#[cfg(not(loom))]
32const _: () = assert!(core::mem::size_of::<SlotMeta>() == 8);
33
34#[repr(C)]
41pub struct VarSlotMeta {
42 pub generation: AtomicU32,
44 pub state: AtomicU32,
46 pub owner_peer: AtomicU32,
49 pub next_free: AtomicU32,
51}
52
53#[cfg(not(loom))]
54const _: () = assert!(core::mem::size_of::<VarSlotMeta>() == 16);
55
56impl VarSlotMeta {
57 #[inline]
59 pub fn init(&mut self) {
60 self.generation = AtomicU32::new(0);
61 self.state = AtomicU32::new(SlotState::Free as u32);
62 self.owner_peer = AtomicU32::new(0);
63 self.next_free = AtomicU32::new(u32::MAX);
64 }
65
66 #[inline]
68 pub fn generation(&self) -> u32 {
69 self.generation.load(Ordering::Acquire)
70 }
71
72 #[inline]
74 pub fn state(&self) -> SlotState {
75 SlotState::from_u32(self.state.load(Ordering::Acquire)).unwrap_or(SlotState::Free)
76 }
77
78 #[inline]
80 pub fn owner(&self) -> u8 {
81 self.owner_peer.load(Ordering::Acquire) as u8
82 }
83
84 #[inline]
86 pub fn next_free(&self) -> u32 {
87 self.next_free.load(Ordering::Acquire)
88 }
89
90 #[inline]
92 pub fn check_generation(&self, expected: u32) -> bool {
93 self.generation.load(Ordering::Acquire) == expected
94 }
95}
96
97impl SlotMeta {
98 #[inline]
100 pub fn init(&mut self) {
101 self.generation = AtomicU32::new(0);
102 self.state = AtomicU32::new(SlotState::Free as u32);
103 }
104
105 #[inline]
109 pub fn try_transition(&self, expected: SlotState, new: SlotState) -> Result<u32, SlotState> {
110 match self.state.compare_exchange(
111 expected as u32,
112 new as u32,
113 Ordering::AcqRel,
114 Ordering::Acquire,
115 ) {
116 Ok(_) => Ok(self.generation.load(Ordering::Acquire)),
117 Err(actual) => Err(SlotState::from_u32(actual).unwrap_or(SlotState::Free)),
118 }
119 }
120
121 #[inline]
123 pub fn check_generation(&self, expected: u32) -> bool {
124 self.generation.load(Ordering::Acquire) == expected
125 }
126
127 #[inline]
129 pub fn generation(&self) -> u32 {
130 self.generation.load(Ordering::Acquire)
131 }
132
133 #[inline]
135 pub fn state(&self) -> SlotState {
136 SlotState::from_u32(self.state.load(Ordering::Acquire)).unwrap_or(SlotState::Free)
137 }
138}