use crate::variant::cell::UnsafeCell;
use crate::variant::sync::atomic::AtomicUsize;
use crate::variant::thread;
use std::mem::MaybeUninit;
use std::sync::atomic::Ordering;
#[derive(Debug)]
pub(crate) struct Slot<T> {
pub(crate) item: UnsafeCell<MaybeUninit<T>>,
pub(crate) state: AtomicUsize,
}
impl<T> Slot<T> {
#[cfg(not(loom))]
pub(crate) const UNINIT: Slot<T> = Self {
item: UnsafeCell::new(MaybeUninit::uninit()),
state: AtomicUsize::new(0),
};
#[cfg(loom)]
pub(crate) fn new() -> Self {
Self {
item: UnsafeCell::new(MaybeUninit::uninit()),
state: AtomicUsize::new(0),
}
}
pub(crate) fn wait_filled(&self) {
while self.state.load(Ordering::Acquire) & FILLED == 0 {
thread::yield_now()
}
}
}
#[cfg(loom)]
impl<T> Default for Slot<T> {
fn default() -> Self {
Self::new()
}
}
pub(crate) const FILLED: usize = 1;
pub(crate) const READING: usize = 2;
pub(crate) const DRAINING: usize = 4;