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]
spin_lock_irqsave(lock: *mut spinlock_t, flags: &mut u64)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]
spin_unlock_irqrestore(lock: *mut spinlock_t, flags: &u64)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]
spin_is_locked(lock: &spinlock_t) -> bool32 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 {
default() -> Self39 fn default() -> Self {
40 Self { lock: 1 }
41 }
42 }
43
44 /// @brief 关闭中断并加锁
spin_lock_irq(lock: *mut spinlock_t)45 pub fn spin_lock_irq(lock: *mut spinlock_t) {
46 cli();
47 unsafe {
48 spin_lock(lock);
49 }
50 }
51
52 /// @brief 解锁并开中断
spin_unlock_irq(lock: *mut spinlock_t)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 加锁
lock(&mut self)72 pub fn lock(&mut self) {
73 while !self.try_lock() {}
74 }
75
76 /// @brief 关中断并加锁
lock_irq(&mut self)77 pub fn lock_irq(&mut self){
78 cli();
79 self.lock();
80 }
81
82 /// @brief 尝试加锁
83 /// @return 加锁成功->true
84 /// 加锁失败->false
try_lock(&mut self) -> bool85 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 解锁
unlock(&mut self)102 pub fn unlock(&mut self){
103 // 减少自旋锁持有计数
104 preempt_enable();
105 self.0.store(false, Ordering::Release);
106 }
107
108 /// @brief 放锁并开中断
unlock_irq(&mut self)109 pub fn unlock_irq(&mut self){
110 self.unlock();
111 sti();
112 }
113
114 /// @brief 判断自旋锁是否被上锁
115 ///
116 /// @return true 自旋锁被上锁
117 /// @return false 自旋锁处于解锁状态
is_locked(&self)->bool118 pub fn is_locked(&self)->bool
119 {
120 return self.0.load(Ordering::Relaxed).into();
121 }
122
123 /// @brief 强制设置自旋锁的状态
124 /// 请注意,这样操作可能会带来未知的风险。因此它是unsafe的。(尽管从Rust语言本身来说,它是safe的)
set_value(&mut self, value:bool)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