use super::*;
use std::sync::atomic::Ordering;
#[allow(dead_code)]
pub struct PositionMonitor<T: 'static> {
read_epoch: Arc<AtomicU64>,
fifo: Fifo<T>,
}
#[allow(dead_code)]
pub struct ReadPosition(u64);
#[allow(dead_code)]
pub struct WritePosition(u64);
impl<T> PositionMonitor<T> {
#[allow(dead_code)]
pub (crate) fn new(read_epoch: Arc<AtomicU64>,fifo: Fifo<T>) -> PositionMonitor<T> {
PositionMonitor {
read_epoch,
fifo,
}
}
pub fn read_position(&self) -> ReadPosition {
let current = self.fifo.current_offsets(Ordering::Relaxed);
let read_epoch = self.read_epoch.load(Ordering::Relaxed);
ReadPosition((read_epoch << 32) | (current.read_offset() as u64))
}
pub fn write_position(&self) -> WritePosition {
let current = self.fifo.current_offsets(Ordering::Relaxed);
let mut write_epoch = self.read_epoch.load(Ordering::Relaxed);
if current.read_high_bit() != current.write_high_bit() {
write_epoch += 1;
}
WritePosition((write_epoch << 32) | (current.write_offset() as u64))
}
}
impl<T> Clone for PositionMonitor<T> {
fn clone(&self) -> Self {
Self {
read_epoch: self.read_epoch.clone(),
fifo: self.fifo.clone(),
}
}
}
impl ReadPosition {
pub fn is_past(&self, write: &WritePosition) -> Option<bool> {
let (read, write) = (self.0, write.0);
let hr = read & (1 << 63);
let hw = write & (1 << 63);
if hr == hw {
Some(read > write)
} else {
None
}
}
}