use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
pub struct AtomicCounter(AtomicU64);
impl AtomicCounter {
pub const fn new(initial: u64) -> Self {
Self(AtomicU64::new(initial))
}
pub fn increment(&self) {
self.0.fetch_add(1, Ordering::Relaxed);
}
pub fn add(&self, value: u64) {
self.0.fetch_add(value, Ordering::Relaxed);
}
pub fn get(&self) -> u64 {
self.0.load(Ordering::Relaxed)
}
pub fn reset(&self) {
self.0.store(0, Ordering::Relaxed);
}
}
impl Default for AtomicCounter {
fn default() -> Self {
Self::new(0)
}
}
pub struct AtomicGauge(AtomicUsize);
impl AtomicGauge {
pub const fn new(initial: usize) -> Self {
Self(AtomicUsize::new(initial))
}
pub fn add(&self, value: usize) -> usize {
self.0.fetch_add(value, Ordering::Relaxed) + value
}
pub fn sub(&self, value: usize) -> usize {
self.0.fetch_sub(value, Ordering::Relaxed) - value
}
pub fn get(&self) -> usize {
self.0.load(Ordering::Relaxed)
}
pub fn set(&self, value: usize) {
self.0.store(value, Ordering::Relaxed);
}
pub fn update_max(&self, value: usize) {
let mut current = self.0.load(Ordering::Relaxed);
while value > current {
match self.0.compare_exchange_weak(
current,
value,
Ordering::Relaxed,
Ordering::Relaxed,
) {
Ok(_) => break,
Err(c) => current = c,
}
}
}
}
impl Default for AtomicGauge {
fn default() -> Self {
Self::new(0)
}
}