use core::sync::atomic::{AtomicBool, Ordering};
use crate::WaitQueue;
pub struct IrqNotify {
pending: AtomicBool,
wait: WaitQueue,
}
impl Default for IrqNotify {
fn default() -> Self {
Self::new()
}
}
impl IrqNotify {
pub const fn new() -> Self {
Self {
pending: AtomicBool::new(false),
wait: WaitQueue::new(),
}
}
pub fn notify_irq(&self) {
self.pending.store(true, Ordering::Release);
self.wait.notify_one_from_irq();
}
pub fn notify(&self) {
self.pending.store(true, Ordering::Release);
self.wait.notify_one(true);
}
pub fn is_pending(&self) -> bool {
self.pending.load(Ordering::Acquire)
}
pub fn drain(&self) -> bool {
self.pending.swap(false, Ordering::AcqRel)
}
#[track_caller]
pub fn wait(&self) {
self.wait.wait_until(|| self.drain());
}
}