use std::sync::Arc;
use std::sync::atomic::{AtomicBool, AtomicI64, Ordering};
#[derive(Debug, Clone)]
pub struct AtomicCounter {
inner: Arc<AtomicI64>,
name: Option<String>,
}
impl AtomicCounter {
pub fn new(initial: i64) -> Self {
Self {
inner: Arc::new(AtomicI64::new(initial)),
name: None,
}
}
pub fn with_name(initial: i64, name: String) -> Self {
Self {
inner: Arc::new(AtomicI64::new(initial)),
name: Some(name),
}
}
pub fn get(&self) -> i64 {
self.inner.load(Ordering::SeqCst)
}
pub fn set(&self, value: i64) {
self.inner.store(value, Ordering::SeqCst);
}
pub fn increment(&self) -> i64 {
self.inner.fetch_add(1, Ordering::SeqCst) + 1
}
pub fn decrement(&self) -> i64 {
self.inner.fetch_sub(1, Ordering::SeqCst) - 1
}
pub fn add(&self, value: i64) -> i64 {
self.inner.fetch_add(value, Ordering::SeqCst) + value
}
pub fn sub(&self, value: i64) -> i64 {
self.inner.fetch_sub(value, Ordering::SeqCst) - value
}
pub fn compare_and_swap(&self, current: i64, new: i64) -> i64 {
self.inner.compare_exchange(current, new, Ordering::SeqCst, Ordering::SeqCst)
.unwrap_or_else(|x| x)
}
pub fn name(&self) -> Option<&str> {
self.name.as_deref()
}
}
#[derive(Debug, Clone)]
pub struct AtomicFlag {
inner: Arc<AtomicBool>,
name: Option<String>,
}
impl AtomicFlag {
pub fn new(initial: bool) -> Self {
Self {
inner: Arc::new(AtomicBool::new(initial)),
name: None,
}
}
pub fn with_name(initial: bool, name: String) -> Self {
Self {
inner: Arc::new(AtomicBool::new(initial)),
name: Some(name),
}
}
pub fn get(&self) -> bool {
self.inner.load(Ordering::SeqCst)
}
pub fn set(&self, value: bool) {
self.inner.store(value, Ordering::SeqCst);
}
pub fn set_true(&self) -> bool {
self.inner.swap(true, Ordering::SeqCst)
}
pub fn set_false(&self) -> bool {
self.inner.swap(false, Ordering::SeqCst)
}
pub fn compare_and_swap(&self, current: bool, new: bool) -> bool {
self.inner.compare_exchange(current, new, Ordering::SeqCst, Ordering::SeqCst)
.unwrap_or_else(|x| x)
}
pub fn name(&self) -> Option<&str> {
self.name.as_deref()
}
}