use core::hint;
use core::mem;
use core::mem::MaybeUninit;
use crate::reclaim::Atomic;
use crate::reclaim::Collector;
use crate::reclaim::CollectorWeak;
use crate::reclaim::Shared;
use crate::sync::atomic::Ordering;
const NO_TAG: sdd::Tag = sdd::Tag::None;
pub enum Sdd {}
unsafe impl Collector for Sdd {}
impl CollectorWeak for Sdd {
type Guard = sdd::Guard;
type Atomic<T> = sdd::AtomicOwned<T>;
#[inline]
fn guard() -> Self::Guard {
sdd::Guard::new()
}
#[inline]
fn flush() {
const EPOCH: usize = 4;
for _ in 0..EPOCH {
Self::guard().accelerate();
}
}
}
impl<T> Atomic<T> for sdd::AtomicOwned<T> {
type Guard = sdd::Guard;
#[rustfmt::skip]
type Shared<'guard> = sdd::Ptr<'guard, T>
where
T: 'guard;
#[inline]
fn null() -> Self {
Self::null()
}
#[inline]
fn read<'guard>(&self, order: Ordering, guard: &'guard Self::Guard) -> Self::Shared<'guard> {
self.load(order, guard)
}
#[inline]
fn write(&self, order: Ordering, init: impl FnOnce(&mut MaybeUninit<T>))
where
T: 'static,
{
let value: sdd::Owned<T> = sdd::Owned::new_with(|| {
let mut uninit: MaybeUninit<T> = MaybeUninit::uninit();
init(&mut uninit);
unsafe { uninit.assume_init() }
});
let old: (Option<sdd::Owned<T>>, sdd::Tag) = self.swap((Some(value), NO_TAG), order);
debug_assert!(old.0.is_none(), "Atomic<T> is occupied!");
debug_assert!(old.1 == NO_TAG, "Atomic<T> is tagged!");
unsafe {
hint::assert_unchecked(old.0.is_none());
hint::assert_unchecked(old.1 == NO_TAG);
}
}
#[inline]
fn evict(&self, order: Ordering) -> bool {
self.swap((None, NO_TAG), order).0.is_some()
}
#[inline]
unsafe fn clear(&mut self) -> bool {
let entry: Self = mem::take(self);
if let Some(value) = entry.into_owned(Ordering::Relaxed) {
unsafe {
value.drop_in_place();
}
true
} else {
false
}
}
}
impl<'guard, T> Shared<'guard, T> for sdd::Ptr<'guard, T> {
#[inline]
fn is_null(&self) -> bool {
self.is_null()
}
#[inline]
fn as_ref(&self) -> Option<&'guard T> {
unsafe { self.as_ref_unchecked() }
}
}