use yog_sync::atomic::{AtomicU32, Ordering, fence};
#[inline]
pub fn begin(seq: &AtomicU32) -> u32 {
let s = seq.load(Ordering::Relaxed);
seq.store(s.wrapping_add(1), Ordering::Relaxed);
fence(Ordering::Release);
s
}
#[inline]
pub fn end(seq: &AtomicU32, began: u32) {
seq.store(began.wrapping_add(2), Ordering::Release);
}
#[inline]
pub fn read<T>(seq: &AtomicU32, mut read: impl FnMut() -> T) -> T {
loop {
let before = seq.load(Ordering::Acquire);
if before & 1 == 0 {
let value = read();
fence(Ordering::Acquire);
if seq.load(Ordering::Relaxed) == before {
return value;
}
}
std::hint::spin_loop();
}
}