1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
//! Cross-architecture utilities for temporarily disabling interrupts and signals.
//!
//! This crate allows you to temporarily disable interrupts and then restore the previous state again.
//!
//! Supported platforms:
//!
//! - bare-metal (kernel mode, `target_os = "none"`)
//!
//! Disables hardware interrupts.
//!
//! - AArch64 (`arch = aarch64`)
//!
//! - 64-bit RISC-V (`arch = riscv64`)
//!
//! - x86-64 (`arch = x86_64`)
//!
//! - Unix (user mode, `unix`)
//!
//! Disables signals.
//!
//! On targets with non-unix operating systems (not `cfg!(unix)`), this crate does nothing.
//!
//! # Caveats
//!
//! <div class="warning">Interrupts are disabled on a best-effort basis.</div>
//!
//! Even though this crate makes sure that interrupts are disabled, nothing prevents you from manually enabling them again.
//!
//! [Manually dropping] [`Guard`]s may also cause interrupts to be enabled.
//!
//! [Manually dropping]: Guard#caveats-drop-order
//!
//! # Examples
//!
//! Use [`disable`] to disable interrupts with a guard:
//!
//! ```
//! // interrupts may or may not be enabled
//! let guard = interrupts::disable();
//! // interrupts are disabled
//! drop(guard);
//! // interrupts are restored to the previous state
//! ```
//!
//! Use [`without`] to run a closure with disabled interrupts:
//!
//! ```
//! // interrupts may or may not be enabled
//! interrupts::without(|| {
//! // interrupts are disabled
//! });
//! // interrupts are restored to the previous state
//! ```
//!
//! # Related Crates
//!
//! - [interrupt-ref-cell] (A `RefCell` for sharing data with interrupt handlers or signal handlers on the same thread.)
//! - [interrupt-mutex] (A mutex for sharing data with interrupt handlers or signal handlers.)
//!
//! [interrupt-ref-cell]: https://crates.io/crates/interrupt-ref-cell
//! [interrupt-mutex]: https://crates.io/crates/interrupt-mutex
use PhantomData;
/// Temporarily disable interrupts.
///
/// Interrupts are enabled once the returned [`Guard`] is dropped.
///
/// # Examples
///
/// ```
/// // interrupts may or may not be enabled
/// let guard = interrupts::disable();
/// // interrupts are disabled
/// drop(guard);
/// // interrupts are restored to the previous state
/// ```
/// An interrupt guard.
///
/// Created using [`disable`].
///
/// While an instance of this guard is held, interrupts are disabled.
/// When this guard is dropped, interrupts are restored to the state before disabling.
///
/// # Caveats (Drop Order)
///
/// If interrupts are enabled, acquiring a guard will disable them.
/// Dropping this guard will enable interrupts again.
/// Different [`Guard`]s might be dropped in arbitrary order.
///
/// This may result in interrupts being enabled again, even though another [`Guard`] is still held.
/// For this to happen, one must explicitly drop guards in the wrong order, though.
/// As long as guards don't leave their original [drop scope], they are dropped automatically in the correct order.
///
/// [drop scope]: https://doc.rust-lang.org/reference/destructors.html#drop-scopes
///
/// # Examples
///
/// ```
/// // interrupts may or may not be enabled
/// let guard = interrupts::disable();
/// // interrupts are disabled
/// drop(guard);
/// // interrupts are restored to the previous state
/// ```
///
/// Dropping guards in the wrong order (don't do this):
///
/// ```
/// // Interrupts are enabled
/// let a = interrupts::disable();
/// // Interrupts are disabled
/// let b = interrupts::disable();
/// drop(a);
/// // Interrupts are enabled, although we still hold a guard in b
/// drop(b);
/// ```
/// Run a closure with disabled interrupts.
///
/// Run the given closure, disabling interrupts before running it (if they aren't already disabled).
/// Afterward, interrupts are enabled again if they were enabled before.
///
/// If you have other `enable` and `disable` calls _within_ the closure, things may not work as expected.
///
/// Only has an effect if `target_os = "none"`.
///
/// # Examples
///
/// ```
/// // interrupts may or may not be enabled
/// interrupts::without(|| {
/// // interrupts are disabled
/// });
/// // interrupts are restored to the previous state
/// ```
///
/// Nesting:
///
/// ```
/// // interrupts may be enabled
/// interrupts::without(|| {
/// // interrupts are disabled
/// interrupts::without(|| {
/// // interrupts are disabled
/// });
/// // interrupts are still disabled
/// });
/// // interrupts are restored
/// ```
// Docs adapted from `x86_64::instructions::interrupts::without_interrupts`.