use crate::loom::sync::atomic::Ordering;
use crate::loom::sync::atomic::*;
use std::mem::MaybeUninit;
pub trait NativelyAtomic {
type Atomic: Default;
fn read(slot: &Self::Atomic, ordering: Ordering) -> Self;
fn write(self, slot: &Self::Atomic, ordering: Ordering);
}
macro_rules! impl_for {
($n:ty, $a:ty) => {
impl NativelyAtomic for $n {
type Atomic = $a;
#[inline]
fn read(slot: &Self::Atomic, ordering: Ordering) -> Self {
slot.load(ordering)
}
#[inline]
fn write(self, slot: &Self::Atomic, ordering: Ordering) {
slot.store(self, ordering);
}
}
};
}
impl_for!(u8, AtomicU8);
impl_for!(u16, AtomicU16);
impl_for!(u32, AtomicU32);
impl_for!(u64, AtomicU64);
impl_for!(usize, AtomicUsize);
impl_for!(i8, AtomicI8);
impl_for!(i16, AtomicI16);
impl_for!(i32, AtomicI32);
impl_for!(i64, AtomicI64);
impl_for!(isize, AtomicIsize);
impl_for!(bool, AtomicBool);
impl<T> NativelyAtomic for *mut T {
type Atomic = AtomicPtr<T>;
#[inline]
fn read(slot: &Self::Atomic, ordering: Ordering) -> Self {
slot.load(ordering)
}
#[inline]
fn write(self, slot: &Self::Atomic, ordering: Ordering) {
slot.store(self, ordering);
}
}
impl NativelyAtomic for () {
type Atomic = ();
#[inline]
fn read(_slot: &Self::Atomic, _ordering: Ordering) -> Self {}
#[inline]
fn write(self, _slot: &Self::Atomic, _ordering: Ordering) {}
}
pub struct NativeSlotable;
impl<T: NativelyAtomic> super::Slotable<T> for NativeSlotable {
type Slot = T::Atomic;
type SlotArrayItem = T::Atomic;
fn boxed_uninit_single() -> Box<Self::Slot> {
Box::new(T::Atomic::default())
}
fn read(slot: &Self::Slot, ordering: Ordering) -> MaybeUninit<T> {
MaybeUninit::new(T::read(slot, ordering))
}
fn write(slot: &Self::Slot, value: T, ordering: Ordering) {
value.write(slot, ordering);
}
fn boxed_uninit_multiple(n: usize) -> Box<[Self::SlotArrayItem]> {
std::iter::repeat_with(T::Atomic::default)
.take(n)
.collect::<Vec<_>>()
.into_boxed_slice()
}
fn index_in_array(items: &[Self::SlotArrayItem], index: usize) -> &Self::Slot {
&items[index]
}
}
crate::impl_channels!(crate::native::NativeSlotable, crate::native::NativelyAtomic);