1use crate::loom::sync::atomic::Ordering;
4use crate::loom::sync::atomic::*;
5use std::mem::MaybeUninit;
6
7pub trait NativelyAtomic {
8 type Atomic: Default;
9
10 fn read(slot: &Self::Atomic, ordering: Ordering) -> Self;
11 fn write(self, slot: &Self::Atomic, ordering: Ordering);
12}
13
14macro_rules! impl_for {
15 ($n:ty, $a:ty) => {
16 impl NativelyAtomic for $n {
17 type Atomic = $a;
18
19 #[inline]
20 fn read(slot: &Self::Atomic, ordering: Ordering) -> Self {
21 slot.load(ordering)
22 }
23
24 #[inline]
25 fn write(self, slot: &Self::Atomic, ordering: Ordering) {
26 slot.store(self, ordering);
27 }
28 }
29 };
30}
31
32impl_for!(u8, AtomicU8);
33impl_for!(u16, AtomicU16);
34impl_for!(u32, AtomicU32);
35impl_for!(u64, AtomicU64);
36impl_for!(usize, AtomicUsize);
37impl_for!(i8, AtomicI8);
38impl_for!(i16, AtomicI16);
39impl_for!(i32, AtomicI32);
40impl_for!(i64, AtomicI64);
41impl_for!(isize, AtomicIsize);
42impl_for!(bool, AtomicBool);
43
44impl<T> NativelyAtomic for *mut T {
45 type Atomic = AtomicPtr<T>;
46
47 #[inline]
48 fn read(slot: &Self::Atomic, ordering: Ordering) -> Self {
49 slot.load(ordering)
50 }
51 #[inline]
52 fn write(self, slot: &Self::Atomic, ordering: Ordering) {
53 slot.store(self, ordering);
54 }
55}
56
57impl NativelyAtomic for () {
58 type Atomic = ();
59
60 #[inline]
61 fn read(_slot: &Self::Atomic, _ordering: Ordering) -> Self {}
62 #[inline]
63 fn write(self, _slot: &Self::Atomic, _ordering: Ordering) {}
64}
65
66pub struct NativeSlotable;
67
68impl<T: NativelyAtomic> super::Slotable<T> for NativeSlotable {
69 type Slot = T::Atomic;
70 type SlotArrayItem = T::Atomic;
71
72 fn boxed_uninit_single() -> Box<Self::Slot> {
73 Box::new(T::Atomic::default())
74 }
75
76 fn read(slot: &Self::Slot, ordering: Ordering) -> MaybeUninit<T> {
77 MaybeUninit::new(T::read(slot, ordering))
78 }
79
80 fn write(slot: &Self::Slot, value: T, ordering: Ordering) {
81 value.write(slot, ordering);
82 }
83
84 fn boxed_uninit_multiple(n: usize) -> Box<[Self::SlotArrayItem]> {
85 std::iter::repeat_with(T::Atomic::default)
86 .take(n)
87 .collect::<Vec<_>>()
88 .into_boxed_slice()
89 }
90
91 fn index_in_array(items: &[Self::SlotArrayItem], index: usize) -> &Self::Slot {
92 &items[index]
93 }
94}
95
96crate::impl_channels!(crate::native::NativeSlotable, crate::native::NativelyAtomic);