xref: /DragonOS/kernel/src/libs/spinlock.rs (revision adc1846b06fb862caed049f435fc0061488a6ff9)
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 pub struct RawSpinlock(AtomicBool);
61 
62 impl RawSpinlock {
63     /// @brief 初始化自旋锁
64     const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false));
65 
66     /// @brief 加锁
67     pub fn lock(&mut self) {
68         while !self.try_lock() {}
69     }
70 
71     /// @brief 关中断并加锁
72     pub fn lock_irq(&mut self){
73         cli();
74         self.lock();
75     }
76 
77     /// @brief 尝试加锁
78     /// @return 加锁成功->true
79     ///         加锁失败->false
80     pub fn try_lock(&mut self) -> bool {
81         // 先增加自旋锁持有计数
82         preempt_disable();
83 
84         let res = self
85             .0
86             .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
87             .is_ok();
88 
89         // 如果加锁失败恢复自旋锁持有计数
90         if res == false {
91             preempt_enable();
92         }
93         return res;
94     }
95 
96     /// @brief 解锁
97     pub fn unlock(&mut self){
98         // 减少自旋锁持有计数
99         preempt_enable();
100         self.0.store(false, Ordering::Release);
101     }
102 
103     /// @brief 放锁并开中断
104     pub fn unlock_irq(&mut self){
105         self.unlock();
106         sti();
107     }
108 
109     // todo: spin_lock_irqsave
110     // todo: spin_unlock_irqrestore
111 
112 }
113