1use std::sync::atomic::{AtomicU64, Ordering};
2
3use metrics::GaugeFn;
4
5#[derive(Debug)]
7pub struct AtomicF64(AtomicU64);
8
9impl AtomicF64 {
10 #[must_use]
12 pub fn new(init: f64) -> Self {
13 Self(AtomicU64::new(init.to_bits()))
14 }
15
16 pub fn load(&self, order: Ordering) -> f64 {
17 f64::from_bits(self.0.load(order))
18 }
19
20 #[expect(clippy::missing_panics_doc, reason = "fetch_update always succeeds")]
21 pub fn fetch_update(
22 &self,
23 set_order: Ordering,
24 fetch_order: Ordering,
25 mut f: impl FnMut(f64) -> f64,
26 ) -> f64 {
27 f64::from_bits(
28 self.0
29 .fetch_update(set_order, fetch_order, |x| {
30 Some(f(f64::from_bits(x)).to_bits())
31 })
32 .expect("fetch_update always succeeds"),
33 )
34 }
35}
36
37impl GaugeFn for AtomicF64 {
38 fn increment(&self, amount: f64) {
39 self.fetch_update(Ordering::Relaxed, Ordering::Relaxed, |value| value + amount);
40 }
41
42 fn decrement(&self, amount: f64) {
43 self.fetch_update(Ordering::Relaxed, Ordering::Relaxed, |value| value - amount);
44 }
45
46 fn set(&self, value: f64) {
47 self.0.store(f64::to_bits(value), Ordering::Relaxed);
48 }
49}