ax_task/sync/irq/
worker.rs1use core::time::Duration;
2
3use crate::{
4 runtime::service::reclaim::quiesce_irq_wait,
5 sync::{
6 WaitQueue,
7 irq::{IrqRegisterResult, IrqWaitCell, IrqWaitRegistration},
8 },
9 thread::{
10 TaskError, ThreadWakeHandle,
11 current::park::{CurrentParkStart, begin_current_park},
12 },
13};
14
15#[derive(Debug)]
22pub struct IrqWorkerWaiter {
23 registration: IrqWaitRegistration,
24}
25
26impl IrqWorkerWaiter {
27 pub fn new(wake_owner: ThreadWakeHandle) -> Self {
29 Self {
30 registration: IrqWaitRegistration::new(wake_owner),
31 }
32 }
33
34 pub fn wait(&self, event: &IrqWaitCell) -> Result<(), TaskError> {
41 match event.register(&self.registration) {
42 IrqRegisterResult::Occupied => Err(TaskError::InvalidConfiguration),
43 IrqRegisterResult::ConsumedPending => Ok(()),
44 IrqRegisterResult::Registered(token)
45 | IrqRegisterResult::NotificationInFlight(token) => loop {
46 if !token.is_attached() {
47 return quiesce_irq_wait(token);
48 }
49 match begin_current_park()? {
50 CurrentParkStart::Notified => {}
51 CurrentParkStart::Prepared(park) => {
52 let _resume = park.commit()?;
53 }
54 }
55 },
56 }
57 }
58
59 pub fn wait_timeout(&self, event: &IrqWaitCell, timeout: Duration) -> Result<bool, TaskError> {
66 match event.register(&self.registration) {
67 IrqRegisterResult::Occupied => Err(TaskError::InvalidConfiguration),
68 IrqRegisterResult::ConsumedPending => Ok(false),
69 IrqRegisterResult::Registered(token)
70 | IrqRegisterResult::NotificationInFlight(token) => {
71 let park = WaitQueue::new();
72 let timed_out = park.wait_timeout_until(timeout, || !token.is_attached());
73 quiesce_irq_wait(token)?;
74 Ok(timed_out)
75 }
76 }
77 }
78}