ostd/irq/
guard.rs

1// SPDX-License-Identifier: MPL-2.0
2
3//! The IRQ disabling guard.
4
5use crate::{arch::irq as arch_irq, sync::GuardTransfer, task::atomic_mode::InAtomicMode};
6
7/// Disables all IRQs on the current CPU (i.e., locally).
8///
9/// This function returns a guard object, which will automatically enable local IRQs again when
10/// it is dropped. This function works correctly even when it is called in a _nested_ way.
11/// The local IRQs shall only be re-enabled when the most outer guard is dropped.
12///
13/// This function can play nicely with [`SpinLock`] as the type uses this function internally.
14/// One can invoke this function even after acquiring a spin lock. And the reversed order is also ok.
15///
16/// [`SpinLock`]: crate::sync::SpinLock
17///
18/// # Example
19///
20/// ```rust
21/// use ostd::irq;
22///
23/// {
24///     let _ = irq::disable_local();
25///     todo!("do something when irqs are disabled");
26/// }
27/// ```
28pub fn disable_local() -> DisabledLocalIrqGuard {
29    DisabledLocalIrqGuard::new()
30}
31
32/// A guard for disabled local IRQs.
33#[clippy::has_significant_drop]
34#[must_use]
35#[derive(Debug)]
36pub struct DisabledLocalIrqGuard {
37    was_enabled: bool,
38}
39
40impl !Send for DisabledLocalIrqGuard {}
41
42// SAFETY: The guard disables local IRQs, which meets the first
43// sufficient condition for atomic mode.
44unsafe impl InAtomicMode for DisabledLocalIrqGuard {}
45
46impl DisabledLocalIrqGuard {
47    fn new() -> Self {
48        let was_enabled = arch_irq::is_local_enabled();
49        if was_enabled {
50            arch_irq::disable_local();
51        }
52        Self { was_enabled }
53    }
54}
55
56impl GuardTransfer for DisabledLocalIrqGuard {
57    fn transfer_to(&mut self) -> Self {
58        let was_enabled = self.was_enabled;
59        self.was_enabled = false;
60        Self { was_enabled }
61    }
62}
63
64impl Drop for DisabledLocalIrqGuard {
65    fn drop(&mut self) {
66        if self.was_enabled {
67            arch_irq::enable_local();
68        }
69    }
70}