use crate::signal::SignalQueue;
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
use std::sync::Arc;
use std::thread::{self, JoinHandle};
use std::time::Duration;
pub struct FencePollerState {
pub shutdown: Arc<AtomicBool>,
pub signal_queue: Arc<SignalQueue>,
pub last_emitted_epoch: Arc<AtomicU64>,
pub gpu_completed: Arc<dyn Fn() -> u64 + Send + Sync>,
}
pub fn spawn_fence_poller(state: FencePollerState) -> JoinHandle<()> {
thread::spawn(move || {
while !state.shutdown.load(Ordering::Relaxed) {
let completed = (state.gpu_completed)();
if completed != u64::MAX {
let mut last = state.last_emitted_epoch.load(Ordering::Acquire);
while last < completed {
last += 1;
state.signal_queue.push_boundary_crossed(last);
state.last_emitted_epoch.store(last, Ordering::Release);
}
}
thread::sleep(Duration::from_millis(1));
}
})
}
pub fn join_fence_poller(shutdown: &AtomicBool, handle: Option<JoinHandle<()>>) {
shutdown.store(true, Ordering::Relaxed);
if let Some(h) = handle {
let _ = h.join();
}
}