xref: /DragonOS/kernel/src/libs/spinlock.rs (revision 9358ff0f6f7daa18d6fab4497de025736b3d6725)
1 #![allow(dead_code)]
2 use core::ptr::read_volatile;
3 
4 use core::sync::atomic::{AtomicBool, Ordering};
5 
6 use crate::arch::asm::irqflags::{local_irq_restore, local_irq_save};
7 use crate::arch::interrupt::{cli, sti};
8 use crate::include::bindings::bindings::{spin_lock, spin_unlock, spinlock_t};
9 use crate::process::preempt::{preempt_disable, preempt_enable};
10 
11 /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁
12 #[inline]
13 pub fn spin_lock_irqsave(lock: *mut spinlock_t, flags: &mut u64) {
14     local_irq_save(flags);
15     unsafe {
16         spin_lock(lock);
17     }
18 }
19 
20 /// @brief 恢复rflags以及中断状态并解锁自旋锁
21 #[inline]
22 pub fn spin_unlock_irqrestore(lock: *mut spinlock_t, flags: &u64) {
23     unsafe {
24         spin_unlock(lock);
25     }
26     // kdebug!("123");
27     local_irq_restore(flags);
28 }
29 
30 /// 判断一个自旋锁是否已经被加锁
31 #[inline]
32 pub fn spin_is_locked(lock: &spinlock_t) -> bool {
33     let val = unsafe { read_volatile(&lock.lock as *const i8) };
34 
35     return if val == 0 { true } else { false };
36 }
37 
38 impl Default for spinlock_t {
39     fn default() -> Self {
40         Self { lock: 1 }
41     }
42 }
43 
44 /// @brief 关闭中断并加锁
45 pub fn spin_lock_irq(lock: *mut spinlock_t) {
46     cli();
47     unsafe {
48         spin_lock(lock);
49     }
50 }
51 
52 /// @brief 解锁并开中断
53 pub fn spin_unlock_irq(lock: *mut spinlock_t) {
54     unsafe {
55         spin_unlock(lock);
56     }
57     sti();
58 }
59 
60 /// 原始的Spinlock(自旋锁)
61 /// 请注意,这个自旋锁和C的不兼容。
62 ///
63 /// @param self.0 这个AtomicBool的值为false时,表示没有被加锁。当它为true时,表示自旋锁已经被上锁。
64 #[derive(Debug)]
65 pub struct RawSpinlock(AtomicBool);
66 
67 impl RawSpinlock {
68     /// @brief 初始化自旋锁
69     pub const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false));
70 
71     /// @brief 加锁
72     pub fn lock(&mut self) {
73         while !self.try_lock() {}
74     }
75 
76     /// @brief 关中断并加锁
77     pub fn lock_irq(&mut self){
78         cli();
79         self.lock();
80     }
81 
82     /// @brief 尝试加锁
83     /// @return 加锁成功->true
84     ///         加锁失败->false
85     pub fn try_lock(&mut self) -> bool {
86         // 先增加自旋锁持有计数
87         preempt_disable();
88 
89         let res = self
90             .0
91             .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
92             .is_ok();
93 
94         // 如果加锁失败恢复自旋锁持有计数
95         if res == false {
96             preempt_enable();
97         }
98         return res;
99     }
100 
101     /// @brief 解锁
102     pub fn unlock(&mut self){
103         // 减少自旋锁持有计数
104         preempt_enable();
105         self.0.store(false, Ordering::Release);
106     }
107 
108     /// @brief 放锁并开中断
109     pub fn unlock_irq(&mut self){
110         self.unlock();
111         sti();
112     }
113 
114     /// @brief 判断自旋锁是否被上锁
115     ///
116     /// @return true 自旋锁被上锁
117     /// @return false 自旋锁处于解锁状态
118     pub fn is_locked(&self)->bool
119     {
120         return self.0.load(Ordering::Relaxed).into();
121     }
122 
123     /// @brief 强制设置自旋锁的状态
124     /// 请注意,这样操作可能会带来未知的风险。因此它是unsafe的。(尽管从Rust语言本身来说,它是safe的)
125     pub unsafe fn set_value(&mut self, value:bool){
126         self.0.store(value, Ordering::SeqCst);
127     }
128 
129     // todo: spin_lock_irqsave
130     // todo: spin_unlock_irqrestore
131 
132 }
133