JuliOS/src/drivers/atapi/interrupt.rs
Julien CLEMENT 43eec9621c
All checks were successful
continuous-integration/drone/push Build is passing
cargo-fmt
Signed-off-by: Julien CLEMENT <julien.clement@epita.fr>
2022-12-23 20:07:46 +01:00

57 lines
1.2 KiB
Rust

use core::future::Future;
use core::pin::Pin;
use core::sync::atomic::{AtomicBool, Ordering};
use core::task::{Context, Poll};
use futures_util::task::AtomicWaker;
use lazy_static::lazy_static;
lazy_static! {
pub static ref INTERRUPT_FUTURE: InterruptFuture = InterruptFuture::new();
static ref INTERRUPT: AtomicBool = AtomicBool::new(false);
}
static WAKER: AtomicWaker = AtomicWaker::new();
pub(crate) fn mark_interrupt() {
INTERRUPT.store(true, Ordering::Relaxed);
WAKER.wake();
}
#[derive(Copy, Clone)]
pub struct InterruptFuture {
_private: (),
}
impl InterruptFuture {
pub fn new() -> Self {
InterruptFuture { _private: () }
}
pub fn pop(&self) -> bool {
let res = INTERRUPT.load(Ordering::Relaxed);
INTERRUPT.store(false, Ordering::Relaxed);
res
}
}
impl Future for InterruptFuture {
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
if self.pop() {
return Poll::Ready(());
}
WAKER.register(&cx.waker());
match self.pop() {
true => {
WAKER.take();
Poll::Ready(())
}
false => Poll::Pending,
}
}
}