Skip to main content

copy_channels/
native.rs

1//! Implements channels for types that are "natively" atomic, i.e. most primitives.
2
3use 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);