use crossbeam_utils::CachePadded;
use std::sync::atomic::{AtomicI64, Ordering};
use crate::{Sequence, barrier::NONE};
pub(crate) struct Cursor {
counter: CachePadded<AtomicI64>
}
impl Cursor {
pub(crate) fn new() -> Self {
Self {
counter: CachePadded::new(AtomicI64::new(NONE))
}
}
#[inline]
pub(crate) fn compare_exchange(&self, current: Sequence, next: Sequence) -> Result<i64, i64> {
self.counter.compare_exchange(current, next, Ordering::AcqRel, Ordering::Relaxed)
}
#[inline]
pub(crate) fn store(&self, sequence: Sequence) {
self.counter.store(sequence, Ordering::Release);
}
#[inline]
pub(crate) fn relaxed_value(&self) -> Sequence {
self.counter.load(Ordering::Relaxed)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn cursor_operations() {
let cursor = Cursor::new();
assert_eq!(cursor.compare_exchange(-1, 0).ok().unwrap(), -1);
assert_eq!(cursor.compare_exchange( 0, 1).ok().unwrap(), 0);
assert_eq!(cursor.compare_exchange( 0, 1).err().unwrap(), 1);
cursor.store(100);
assert_eq!(cursor.relaxed_value(), 100);
}
}