1use core::marker::PhantomData;
4
5use crate::interface::{CONTEXT_IRQSAVE, CONTEXT_PREEMPT, CONTEXT_PREEMPT_IRQSAVE, CONTEXT_RAW};
6
7#[doc(hidden)]
9#[inline(always)]
10pub fn irq_save_and_disable() -> usize {
11 crate::interface::context_enter(CONTEXT_IRQSAVE)
12}
13
14#[doc(hidden)]
21#[inline(always)]
22pub unsafe fn irq_restore(state: usize) {
23 crate::interface::context_exit(CONTEXT_IRQSAVE, state);
24}
25
26#[doc(hidden)]
28pub trait GuardState {
29 type State: Clone + Copy;
31
32 fn acquire() -> Self::State;
34
35 fn release(state: Self::State);
37}
38
39#[doc(hidden)]
41pub struct RawState;
42
43#[doc(hidden)]
45pub struct PreemptState;
46
47#[doc(hidden)]
49pub struct IrqSaveState;
50
51#[doc(hidden)]
53pub struct PreemptIrqSaveState;
54
55impl GuardState for RawState {
56 type State = usize;
57
58 fn acquire() -> Self::State {
59 crate::interface::context_enter(CONTEXT_RAW)
60 }
61
62 fn release(state: Self::State) {
63 crate::interface::context_exit(CONTEXT_RAW, state);
64 }
65}
66
67impl GuardState for PreemptState {
68 type State = usize;
69
70 fn acquire() -> Self::State {
71 crate::interface::context_enter(CONTEXT_PREEMPT)
72 }
73
74 fn release(state: Self::State) {
75 crate::interface::context_exit(CONTEXT_PREEMPT, state);
76 }
77}
78
79impl GuardState for IrqSaveState {
80 type State = usize;
81
82 fn acquire() -> Self::State {
83 crate::interface::context_enter(CONTEXT_IRQSAVE)
84 }
85
86 fn release(state: Self::State) {
87 crate::interface::context_exit(CONTEXT_IRQSAVE, state);
88 }
89}
90
91impl GuardState for PreemptIrqSaveState {
92 type State = usize;
93
94 fn acquire() -> Self::State {
95 crate::interface::context_enter(CONTEXT_PREEMPT_IRQSAVE)
96 }
97
98 fn release(state: Self::State) {
99 crate::interface::context_exit(CONTEXT_PREEMPT_IRQSAVE, state);
100 }
101}
102
103pub struct PreemptGuard {
110 state: Option<usize>,
111 _not_send: PhantomData<*mut ()>,
112}
113
114impl PreemptGuard {
115 pub fn new() -> Self {
117 Self {
118 state: Some(PreemptState::acquire()),
119 _not_send: PhantomData,
120 }
121 }
122
123 #[doc(hidden)]
125 pub fn finish_irq_return(mut self) {
126 let state = self
127 .state
128 .take()
129 .expect("IRQ-return preemption state must be present");
130 crate::interface::preempt_exit_from_irq_return(state);
131 }
132}
133
134impl Default for PreemptGuard {
135 fn default() -> Self {
136 Self::new()
137 }
138}
139
140impl Drop for PreemptGuard {
141 fn drop(&mut self) {
142 if let Some(state) = self.state.take() {
143 PreemptState::release(state);
144 }
145 }
146}
147
148pub struct IrqSaveGuard {
155 state: usize,
156 _not_send: PhantomData<*mut ()>,
157}
158
159impl IrqSaveGuard {
160 pub fn new() -> Self {
162 Self {
163 state: IrqSaveState::acquire(),
164 _not_send: PhantomData,
165 }
166 }
167}
168
169impl Default for IrqSaveGuard {
170 fn default() -> Self {
171 Self::new()
172 }
173}
174
175impl Drop for IrqSaveGuard {
176 fn drop(&mut self) {
177 IrqSaveState::release(self.state);
178 }
179}
180
181pub struct PreemptIrqSaveGuard {
191 state: usize,
192 _not_send: PhantomData<*mut ()>,
193}
194
195impl PreemptIrqSaveGuard {
196 pub fn new() -> Self {
198 Self {
199 state: PreemptIrqSaveState::acquire(),
200 _not_send: PhantomData,
201 }
202 }
203}
204
205impl Default for PreemptIrqSaveGuard {
206 fn default() -> Self {
207 Self::new()
208 }
209}
210
211impl Drop for PreemptIrqSaveGuard {
212 fn drop(&mut self) {
213 PreemptIrqSaveState::release(self.state);
214 }
215}