crossbeam_utils/atomic/
consume.rs1#[cfg(not(crossbeam_no_atomic))]
2use core::sync::atomic::Ordering;
3
4pub trait AtomicConsume {
6    type Val;
8
9    fn load_consume(&self) -> Self::Val;
25}
26
27#[cfg(not(crossbeam_no_atomic))]
28#[cfg(all(
35    any(target_arch = "arm", target_arch = "aarch64"),
36    not(any(miri, crossbeam_loom, crossbeam_sanitize_thread)),
37))]
38macro_rules! impl_consume {
39    () => {
40        #[inline]
41        fn load_consume(&self) -> Self::Val {
42            use crate::primitive::sync::atomic::compiler_fence;
43            let result = self.load(Ordering::Relaxed);
44            compiler_fence(Ordering::Acquire);
45            result
46        }
47    };
48}
49
50#[cfg(not(crossbeam_no_atomic))]
51#[cfg(not(all(
52    any(target_arch = "arm", target_arch = "aarch64"),
53    not(any(miri, crossbeam_loom, crossbeam_sanitize_thread)),
54)))]
55macro_rules! impl_consume {
56    () => {
57        #[inline]
58        fn load_consume(&self) -> Self::Val {
59            self.load(Ordering::Acquire)
60        }
61    };
62}
63
64macro_rules! impl_atomic {
65    ($atomic:ident, $val:ty) => {
66        #[cfg(not(crossbeam_no_atomic))]
67        impl AtomicConsume for core::sync::atomic::$atomic {
68            type Val = $val;
69            impl_consume!();
70        }
71        #[cfg(crossbeam_loom)]
72        impl AtomicConsume for loom::sync::atomic::$atomic {
73            type Val = $val;
74            impl_consume!();
75        }
76    };
77}
78
79impl_atomic!(AtomicBool, bool);
80impl_atomic!(AtomicUsize, usize);
81impl_atomic!(AtomicIsize, isize);
82impl_atomic!(AtomicU8, u8);
83impl_atomic!(AtomicI8, i8);
84impl_atomic!(AtomicU16, u16);
85impl_atomic!(AtomicI16, i16);
86#[cfg(any(target_has_atomic = "32", not(target_pointer_width = "16")))]
87impl_atomic!(AtomicU32, u32);
88#[cfg(any(target_has_atomic = "32", not(target_pointer_width = "16")))]
89impl_atomic!(AtomicI32, i32);
90#[cfg(any(
91    target_has_atomic = "64",
92    not(any(target_pointer_width = "16", target_pointer_width = "32")),
93))]
94impl_atomic!(AtomicU64, u64);
95#[cfg(any(
96    target_has_atomic = "64",
97    not(any(target_pointer_width = "16", target_pointer_width = "32")),
98))]
99impl_atomic!(AtomicI64, i64);
100
101#[cfg(not(crossbeam_no_atomic))]
102impl<T> AtomicConsume for core::sync::atomic::AtomicPtr<T> {
103    type Val = *mut T;
104    impl_consume!();
105}
106
107#[cfg(crossbeam_loom)]
108impl<T> AtomicConsume for loom::sync::atomic::AtomicPtr<T> {
109    type Val = *mut T;
110    impl_consume!();
111}