pub mod sync {
super::impl_flag!(sync);
impl crate::AssertMt for Flag {}
}
pub mod unsync {
super::impl_flag!(unsync);
}
macro_rules! impl_flag {
($sync:ident) => {
use std::sync::atomic::Ordering;
use crate::$sync::atomic::AtomicBool;
#[derive(Debug)]
pub struct Flag(AtomicBool);
impl Flag {
pub fn new(val: bool) -> Self {
Flag(AtomicBool::new(val))
}
pub fn get(&self) -> bool {
self.0.load(Ordering::Acquire)
}
pub fn swap(&self, val: bool) -> bool {
self.0.swap(val, Ordering::AcqRel)
}
pub fn flip(&self) -> bool {
let mut current = self.get();
loop {
let new = !current;
match self.0.compare_exchange_weak(
current,
new,
Ordering::AcqRel,
Ordering::Acquire,
) {
Ok(_) => return new,
Err(previous) => current = previous,
}
}
}
}
};
}
use impl_flag;