ostd/task/preempt/
mod.rs

1// SPDX-License-Identifier: MPL-2.0
2
3pub(super) mod cpu_local;
4mod guard;
5
6pub use self::guard::{DisabledPreemptGuard, disable_preempt};
7
8/// Halts the CPU until interrupts if no preemption is required.
9///
10/// This function will return if:
11///  - preemption is required when calling this function,
12///  - preemption is required during halting the CPU, or
13///  - interrupts occur during halting the CPU.
14///
15/// This function will perform preemption before returning if
16/// preemption is required.
17///
18/// # Panics
19///
20/// This function will panic if it is called in the atomic mode
21/// ([`crate::task::atomic_mode`]).
22#[track_caller]
23pub fn halt_cpu() {
24    crate::task::atomic_mode::might_sleep();
25
26    let irq_guard = crate::irq::disable_local();
27
28    if cpu_local::need_preempt() {
29        drop(irq_guard);
30    } else {
31        core::mem::forget(irq_guard);
32        // IRQs were previously enabled (checked by `might_sleep`). So we can re-enable them now.
33        crate::arch::irq::enable_local_and_halt();
34    }
35
36    super::scheduler::might_preempt();
37}