1use std::sync::Arc;
5use std::sync::atomic::AtomicU64;
6use std::sync::atomic::Ordering;
7
8#[derive(Clone)]
10pub struct Gauge(Arc<AtomicU64>);
11
12impl std::fmt::Debug for Gauge {
13 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14 f.debug_tuple("Gauge").field(&self.value()).finish()
15 }
16}
17
18impl Gauge {
19 pub(crate) fn new() -> Self {
20 Self(Default::default())
21 }
22
23 pub fn increment(&self, value: f64) {
25 loop {
26 if self
27 .0
28 .fetch_update(Ordering::AcqRel, Ordering::Relaxed, |current| {
29 let input = f64::from_bits(current);
30 Some((input + value).to_bits())
31 })
32 .is_ok()
33 {
34 break;
35 }
36 }
37 }
38
39 pub fn decrement(&self, value: f64) {
41 loop {
42 if self
43 .0
44 .fetch_update(Ordering::AcqRel, Ordering::Relaxed, |current| {
45 let input = f64::from_bits(current);
46 Some((input - value).to_bits())
47 })
48 .is_ok()
49 {
50 break;
51 }
52 }
53 }
54
55 pub fn set(&self, value: f64) {
57 _ = self.0.swap(value.to_bits(), Ordering::AcqRel);
60 }
61
62 pub fn value(&self) -> f64 {
64 let value = self.0.load(Ordering::Acquire);
65 f64::from_bits(value)
66 }
67}