sel4_microkit_base/
defer.rs
1use crate::{Channel, IrqAckError};
8
9#[allow(unused_imports)]
11use crate::Handler;
12
13#[derive(Debug, Copy, Clone, Eq, PartialEq)]
15pub struct DeferredAction {
16 channel: Channel,
17 interface: DeferredActionInterface,
18}
19
20#[derive(Debug, Copy, Clone, Eq, PartialEq)]
22pub enum DeferredActionInterface {
23 Notify,
24 IrqAck,
25}
26
27impl DeferredAction {
28 pub fn new(channel: Channel, interface: DeferredActionInterface) -> Self {
29 Self { channel, interface }
30 }
31
32 pub fn new_notify(channel: Channel) -> DeferredAction {
33 DeferredAction::new(channel, DeferredActionInterface::Notify)
34 }
35
36 pub fn new_irq_ack(channel: Channel) -> DeferredAction {
37 DeferredAction::new(channel, DeferredActionInterface::IrqAck)
38 }
39
40 pub fn channel(&self) -> Channel {
41 self.channel
42 }
43
44 pub fn interface(&self) -> DeferredActionInterface {
45 self.interface
46 }
47
48 pub fn execute_now(self) -> Result<(), IrqAckError> {
49 match self.interface() {
50 DeferredActionInterface::Notify => {
51 self.channel().notify();
52 Ok(())
53 }
54 DeferredActionInterface::IrqAck => self.channel().irq_ack(),
55 }
56 }
57
58 pub(crate) fn prepare(&self) -> PreparedDeferredAction {
59 match self.interface() {
60 DeferredActionInterface::Notify => PreparedDeferredAction::new(
61 self.channel().notification().cast(),
62 sel4::MessageInfoBuilder::default().build(),
63 ),
64 DeferredActionInterface::IrqAck => PreparedDeferredAction::new(
65 self.channel().irq_handler().cast(),
66 sel4::MessageInfoBuilder::default()
67 .label(sel4::sys::invocation_label::IRQAckIRQ.into())
68 .build(),
69 ),
70 }
71 }
72}
73
74#[derive(Debug, Clone, Eq, PartialEq)]
75pub(crate) struct PreparedDeferredAction {
76 cptr: sel4::cap::Unspecified,
77 msg_info: sel4::MessageInfo,
78}
79
80impl PreparedDeferredAction {
81 pub(crate) fn new(cptr: sel4::cap::Unspecified, msg_info: sel4::MessageInfo) -> Self {
82 Self { cptr, msg_info }
83 }
84
85 pub(crate) fn cptr(&self) -> sel4::cap::Unspecified {
86 self.cptr
87 }
88
89 pub(crate) fn msg_info(&self) -> sel4::MessageInfo {
90 self.msg_info.clone() }
92}
93
94pub struct DeferredActionSlot {
97 inner: Option<DeferredAction>,
98}
99
100impl DeferredActionSlot {
101 pub const fn new() -> Self {
102 Self { inner: None }
103 }
104
105 pub fn take(&mut self) -> Option<DeferredAction> {
106 self.inner.take()
107 }
108
109 pub fn defer(&mut self, action: DeferredAction) -> Result<(), IrqAckError> {
110 self.inner
111 .replace(action)
112 .map(DeferredAction::execute_now)
113 .unwrap_or(Ok(()))
114 }
115
116 pub fn defer_notify(&mut self, channel: Channel) -> Result<(), IrqAckError> {
117 self.defer(DeferredAction::new_notify(channel))
118 }
119
120 pub fn defer_irq_ack(&mut self, channel: Channel) -> Result<(), IrqAckError> {
121 self.defer(DeferredAction::new_irq_ack(channel))
122 }
123}
124
125impl Default for DeferredActionSlot {
126 fn default() -> Self {
127 Self::new()
128 }
129}