Skip to main content

ostd/task/preempt/
guard.rs

1// SPDX-License-Identifier: MPL-2.0
2
3use crate::{sync::GuardTransfer, task::atomic_mode::InAtomicMode};
4
5/// A guard for disable preempt.
6#[clippy::has_significant_drop]
7#[must_use]
8#[derive(Debug)]
9pub struct DisabledPreemptGuard {
10    // This private field prevents user from constructing values of this type directly.
11    _private: (),
12}
13
14impl !Send for DisabledPreemptGuard {}
15
16// Required by `InAtomicMode`. See the safety section of its doc comments.
17impl !Sync for DisabledPreemptGuard {}
18
19// SAFETY:
20// 1. The guard disables preemptions;
21// 2. The guard cannot be moved to or used by other tasks.
22unsafe impl InAtomicMode for DisabledPreemptGuard {}
23
24impl DisabledPreemptGuard {
25    fn new() -> Self {
26        super::cpu_local::inc_guard_count();
27        Self { _private: () }
28    }
29}
30
31impl GuardTransfer for DisabledPreemptGuard {
32    fn transfer_to(&mut self) -> Self {
33        disable_preempt()
34    }
35}
36
37impl Drop for DisabledPreemptGuard {
38    fn drop(&mut self) {
39        super::cpu_local::dec_guard_count();
40    }
41}
42
43/// Disables preemption.
44pub fn disable_preempt() -> DisabledPreemptGuard {
45    DisabledPreemptGuard::new()
46}