include!("seq_lock_common.rs");
use core::sync::atomic::AtomicU32;
pub(super) type State = u32;
pub(super) struct SeqLock {
state_hi: AtomicU32,
state: AtomicU32,
}
impl SeqLock {
#[inline]
pub(super) const fn new() -> Self {
Self { state_hi: AtomicU32::new(0), state: AtomicU32::new(0) }
}
#[inline]
pub(super) fn optimistic_read(&self) -> Option<(State, State)> {
let state_hi = self.state_hi.load(Ordering::Acquire);
let state_lo = self.state.load(Ordering::Acquire);
if state_lo == LOCKED { None } else { Some((state_hi, state_lo)) }
}
#[inline]
pub(super) fn validate_read(&self, stamp: (State, State)) -> bool {
crate::fence(Ordering::Acquire);
let state_lo = self.state.load(Ordering::Acquire);
let state_hi = self.state_hi.load(Ordering::Relaxed);
(state_hi, state_lo) == stamp
}
}
impl SeqLockWriteGuard<'_> {
#[inline]
fn next_stamp(&self) -> State {
let state_lo = self.state.wrapping_add(2);
if state_lo == 0 {
let state_hi = self.lock.state_hi.load(Ordering::Relaxed);
self.lock.state_hi.store(state_hi.wrapping_add(1), Ordering::Release);
}
state_lo
}
}