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}