use crate::sync::{AtomicU32, Ordering};
#[repr(u32)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum SlotState {
Free = 0,
Allocated = 1,
}
impl SlotState {
#[inline]
pub fn from_u32(v: u32) -> Option<Self> {
match v {
0 => Some(SlotState::Free),
1 => Some(SlotState::Allocated),
_ => None,
}
}
}
#[repr(C)]
pub struct VarSlotMeta {
pub generation: AtomicU32,
pub state: AtomicU32,
pub owner_peer: AtomicU32,
pub next_free: AtomicU32,
}
#[cfg(not(loom))]
const _: () = assert!(core::mem::size_of::<VarSlotMeta>() == 16);
impl VarSlotMeta {
#[inline]
pub fn init(&mut self) {
self.generation = AtomicU32::new(0);
self.state = AtomicU32::new(SlotState::Free as u32);
self.owner_peer = AtomicU32::new(0);
self.next_free = AtomicU32::new(u32::MAX);
}
#[inline]
pub fn generation(&self) -> u32 {
self.generation.load(Ordering::Acquire)
}
#[inline]
pub fn state(&self) -> SlotState {
SlotState::from_u32(self.state.load(Ordering::Acquire)).unwrap_or(SlotState::Free)
}
#[inline]
pub fn owner(&self) -> u8 {
self.owner_peer.load(Ordering::Acquire) as u8
}
#[inline]
pub fn next_free(&self) -> u32 {
self.next_free.load(Ordering::Acquire)
}
#[inline]
pub fn check_generation(&self, expected: u32) -> bool {
self.generation.load(Ordering::Acquire) == expected
}
}