once/
std_or_loom.rs

1//! This module provides a way to use the standard library or loom's types in a unified way,
2//! depending on the `loom` cfg flag.
3
4#[cfg(not(loom))]
5pub(crate) use std::*;
6
7#[cfg(loom)]
8pub(crate) use loom::*;
9
10/// A trait for getting the inner value of an atomic type when we hold a mutable reference.
11///
12/// We could just use `get_mut` directly, but loom's atomic types do not implement `get_mut`.
13/// Instead, we just get it atomically, since performance doesn't matter so much in tests.
14pub trait GetMut {
15    type Inner;
16
17    /// Use the fact that we have a mutable reference to load the value non-atomically.
18    fn get_by_mut(&mut self) -> Self::Inner;
19}
20
21impl GetMut for std::sync::atomic::AtomicU8 {
22    type Inner = u8;
23
24    fn get_by_mut(&mut self) -> Self::Inner {
25        *self.get_mut()
26    }
27}
28
29#[cfg(loom)]
30impl GetMut for loom::sync::atomic::AtomicU8 {
31    type Inner = u8;
32
33    fn get_by_mut(&mut self) -> Self::Inner {
34        self.load(std::sync::atomic::Ordering::Relaxed)
35    }
36}
37
38impl GetMut for std::sync::atomic::AtomicUsize {
39    type Inner = usize;
40
41    fn get_by_mut(&mut self) -> Self::Inner {
42        *self.get_mut()
43    }
44}
45
46#[cfg(loom)]
47impl GetMut for loom::sync::atomic::AtomicUsize {
48    type Inner = usize;
49
50    fn get_by_mut(&mut self) -> Self::Inner {
51        self.load(std::sync::atomic::Ordering::Relaxed)
52    }
53}
54
55impl<T> GetMut for std::sync::atomic::AtomicPtr<T> {
56    type Inner = *mut T;
57
58    fn get_by_mut(&mut self) -> Self::Inner {
59        *self.get_mut()
60    }
61}
62
63#[cfg(loom)]
64impl<T> GetMut for loom::sync::atomic::AtomicPtr<T> {
65    type Inner = *mut T;
66
67    fn get_by_mut(&mut self) -> Self::Inner {
68        self.load(std::sync::atomic::Ordering::Relaxed)
69    }
70}