cuprate_helper/
atomic.rs

1//! Atomic related
2//!
3//! `#[no_std]` compatible.
4
5//---------------------------------------------------------------------------------------------------- Use
6use crossbeam::atomic::AtomicCell;
7
8//---------------------------------------------------------------------------------------------------- Atomic Float
9/// Compile-time assertion that our floats are
10/// lock-free for the target we're building for.
11const _: () = {
12    assert!(
13        AtomicCell::<f32>::is_lock_free(),
14        "32-bit atomics are not supported on this build target."
15    );
16
17    assert!(
18        AtomicCell::<f64>::is_lock_free(),
19        "64-bit atomics are not supported on this build target."
20    );
21};
22
23// SOMEDAY: use a custom float that implements `Eq`
24// so that `compare_exchange()`, `fetch_*()` work.
25
26/// An atomic [`f32`].
27///
28/// This is an alias for
29/// [`crossbeam::atomic::AtomicCell<f32>`](https://docs.rs/crossbeam/latest/crossbeam/atomic/struct.AtomicCell.html).
30///
31/// Note that there are no [Ordering] parameters,
32/// atomic loads use [Acquire],
33/// and atomic stores use [Release].
34///
35/// [Ordering]: std::sync::atomic::Ordering
36/// [Acquire]: std::sync::atomic::Ordering::Acquire
37/// [Release]: std::sync::atomic::Ordering::Release
38pub type AtomicF32 = AtomicCell<f32>;
39
40/// An atomic [`f64`].
41///
42/// This is an alias for
43/// [`crossbeam::atomic::AtomicCell<f64>`](https://docs.rs/crossbeam/latest/crossbeam/atomic/struct.AtomicCell.html).
44///
45/// Note that there are no [Ordering] parameters,
46/// atomic loads use [Acquire],
47/// and atomic stores use [Release].
48///
49/// [Ordering]: std::sync::atomic::Ordering
50/// [Acquire]: std::sync::atomic::Ordering::Acquire
51/// [Release]: std::sync::atomic::Ordering::Release
52pub type AtomicF64 = AtomicCell<f64>;
53
54//---------------------------------------------------------------------------------------------------- TESTS
55#[cfg(test)]
56mod tests {
57    #![allow(clippy::float_cmp)]
58
59    use super::*;
60
61    #[test]
62    // Tests `AtomicF32`.
63    fn f32() {
64        let float = AtomicF32::new(5.0);
65
66        // Loads/Stores
67        assert_eq!(float.swap(1.0), 5.0);
68        assert_eq!(float.load(), 1.0);
69        float.store(2.0);
70        assert_eq!(float.load(), 2.0);
71    }
72
73    #[test]
74    // Tests `AtomicF64`.
75    fn f64() {
76        let float = AtomicF64::new(5.0);
77
78        // Loads/Stores
79        assert_eq!(float.swap(1.0), 5.0);
80        assert_eq!(float.load(), 1.0);
81        float.store(2.0);
82        assert_eq!(float.load(), 2.0);
83    }
84}