os/sync/
raw_spin_lock_without_guard.rs

1//! Raw spin lock without guard, specifically designed for Global Allocator integration
2//!
3//! This module provides a spin lock implementation that integrates with `lock_api::RawMutex`
4//! for use with the `talc` allocator's `Talck` type.
5//!
6//! # Key Differences from `RawSpinLock`
7//!
8//! - Implements `lock_api::RawMutex` trait
9//! - Does not return a Guard from `lock()` method
10//! - Stores interrupt state internally using `AtomicUsize`
11//! - Unlock operation restores the interrupt state
12//!
13//! # Interrupt Safety
14//!
15//! This lock provides interrupt protection to prevent deadlocks when:
16//! - A thread holds the allocator lock
17//! - An interrupt occurs on the same CPU
18//! - The interrupt handler tries to allocate memory
19//!
20//! Without interrupt protection, this would cause a deadlock.
21
22use crate::arch::intr::{read_and_disable_interrupts, restore_interrupts};
23use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
24
25/// 自旋锁结构体,不返回 Guard,集成了中断状态保存与恢复功能。
26pub struct RawSpinLockWithoutGuard {
27    locked: AtomicBool,
28    saved_intr_flags: AtomicUsize,
29}
30
31impl RawSpinLockWithoutGuard {
32    /// 创建一个新的 RawSpinLockWithoutGuard 实例。
33    pub const fn new() -> Self {
34        Self {
35            locked: AtomicBool::new(false),
36            saved_intr_flags: AtomicUsize::new(0),
37        }
38    }
39}
40
41unsafe impl lock_api::RawMutex for RawSpinLockWithoutGuard {
42    #[allow(clippy::declare_interior_mutable_const)]
43    const INIT: Self = Self::new();
44
45    type GuardMarker = lock_api::GuardNoSend;
46
47    /// 获取锁,禁用中断并保存状态。
48    fn lock(&self) {
49        // 1. Disabldde interrupts and save the flags
50        let flags = unsafe { read_and_disable_interrupts() };
51
52        // 2. Spin until we acquire the lock
53        while self
54            .locked
55            .compare_exchange_weak(false, true, Ordering::Acquire, Ordering::Relaxed)
56            .is_err()
57        {
58            core::hint::spin_loop();
59        }
60
61        // 3. Store the interrupt flags for later restoration
62        self.saved_intr_flags.store(flags, Ordering::Release);
63    }
64
65    /// 尝试获取锁,成功则禁用中断并保存状态。
66    fn try_lock(&self) -> bool {
67        // 1. Disable interrupts and save the flags
68        let flags = unsafe { read_and_disable_interrupts() };
69
70        // 2. Try to acquire the lock
71        if self
72            .locked
73            .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
74            .is_ok()
75        {
76            // 3. Success: store the interrupt flags
77            self.saved_intr_flags.store(flags, Ordering::Release);
78            true
79        } else {
80            // 4. Failed: restore interrupts immediately
81            unsafe { restore_interrupts(flags) };
82            false
83        }
84    }
85
86    /// 释放锁,恢复之前的中断状态。
87    unsafe fn unlock(&self) {
88        // 1. Load the saved interrupt flags
89        let flags = self.saved_intr_flags.load(Ordering::Acquire);
90
91        // 2. Release the lock
92        self.locked.store(false, Ordering::Release);
93
94        // 3. Restore the interrupt state
95        unsafe { restore_interrupts(flags) };
96    }
97}
98
99// Safety: 锁的使用保证了多线程环境下的正确性
100unsafe impl Send for RawSpinLockWithoutGuard {}
101unsafe impl Sync for RawSpinLockWithoutGuard {}
102
103#[cfg(test)]
104mod tests {
105    use lock_api::RawMutex;
106
107    use super::*;
108    use crate::{kassert, test_case};
109
110    // 使用 lock_api::Mutex 包装进行基本功能测试
111    test_case!(test_mutex_wrapper_guard_basic, {
112        let m = lock_api::Mutex::<RawSpinLockWithoutGuard, usize>::new(0);
113
114        {
115            let mut g = m.lock();
116            *g = 42;
117        } // guard drop -> 解锁
118
119        {
120            let g = m.lock();
121            kassert!(*g == 42);
122        }
123    });
124
125    // try_lock 成功/失败与解锁后的可重入获取
126    test_case!(test_try_lock_and_unlock_roundtrip, {
127        let raw = RawSpinLockWithoutGuard::new();
128
129        // 第一次尝试应成功
130        let ok = raw.try_lock();
131        kassert!(ok);
132
133        // 持有锁时第二次尝试应失败
134        let fail = raw.try_lock();
135        kassert!(!fail);
136
137        // 解锁
138        unsafe {
139            raw.unlock();
140        }
141
142        // 解锁后应可再次获取
143        let ok2 = raw.try_lock();
144        kassert!(ok2);
145
146        // 再次解锁,避免影响其他用例
147        unsafe {
148            raw.unlock();
149        }
150    });
151
152    // lock() 获取(在未持锁情况下不应阻塞),随后解锁
153    test_case!(test_lock_then_unlock, {
154        let raw = RawSpinLockWithoutGuard::new();
155
156        // 未持锁情况下 lock() 应立即返回并持有锁
157        raw.lock();
158
159        // 此时 try_lock 应失败
160        let fail = raw.try_lock();
161        kassert!(!fail);
162
163        // 解锁后应可再次获取
164        unsafe {
165            raw.unlock();
166        }
167        let ok = raw.try_lock();
168        kassert!(ok);
169        unsafe {
170            raw.unlock();
171        }
172    });
173}