xref: /DragonOS/kernel/src/libs/spinlock.rs (revision b11bb1b25676f528ec1b0e1da0af82b4652f70c4)
1 #![allow(dead_code)]
2 use core::cell::UnsafeCell;
3 use core::ops::{Deref, DerefMut};
4 use core::ptr::read_volatile;
5 
6 use core::sync::atomic::{AtomicBool, Ordering};
7 
8 use crate::arch::asm::irqflags::{local_irq_restore, local_irq_save};
9 use crate::arch::interrupt::{cli, sti};
10 use crate::include::bindings::bindings::{spin_lock, spin_unlock, spinlock_t};
11 use crate::process::preempt::{preempt_disable, preempt_enable};
12 use crate::syscall::SystemError;
13 
14 /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁
15 #[inline]
16 pub fn spin_lock_irqsave(lock: *mut spinlock_t, flags: &mut u64) {
17     local_irq_save(flags);
18     unsafe {
19         spin_lock(lock);
20     }
21 }
22 
23 /// @brief 恢复rflags以及中断状态并解锁自旋锁
24 #[inline]
25 pub fn spin_unlock_irqrestore(lock: *mut spinlock_t, flags: &u64) {
26     unsafe {
27         spin_unlock(lock);
28     }
29     // kdebug!("123");
30     local_irq_restore(flags);
31 }
32 
33 /// 判断一个自旋锁是否已经被加锁
34 #[inline]
35 pub fn spin_is_locked(lock: &spinlock_t) -> bool {
36     let val = unsafe { read_volatile(&lock.lock as *const i8) };
37 
38     return if val == 0 { true } else { false };
39 }
40 
41 impl Default for spinlock_t {
42     fn default() -> Self {
43         Self { lock: 1 }
44     }
45 }
46 
47 /// @brief 关闭中断并加锁
48 pub fn spin_lock_irq(lock: *mut spinlock_t) {
49     cli();
50     unsafe {
51         spin_lock(lock);
52     }
53 }
54 
55 /// @brief 解锁并开中断
56 pub fn spin_unlock_irq(lock: *mut spinlock_t) {
57     unsafe {
58         spin_unlock(lock);
59     }
60     sti();
61 }
62 
63 /// 原始的Spinlock(自旋锁)
64 /// 请注意,这个自旋锁和C的不兼容。
65 ///
66 /// @param self.0 这个AtomicBool的值为false时,表示没有被加锁。当它为true时,表示自旋锁已经被上锁。
67 #[derive(Debug)]
68 pub struct RawSpinlock(AtomicBool);
69 
70 impl RawSpinlock {
71     /// @brief 初始化自旋锁
72     pub const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false));
73 
74     /// @brief 加锁
75     pub fn lock(&self) {
76         while !self.try_lock() {}
77     }
78 
79     /// @brief 关中断并加锁
80     pub fn lock_irq(&self) {
81         cli();
82         self.lock();
83     }
84 
85     /// @brief 尝试加锁
86     /// @return 加锁成功->true
87     ///         加锁失败->false
88     pub fn try_lock(&self) -> bool {
89         // 先增加自旋锁持有计数
90         preempt_disable();
91 
92         let res = self
93             .0
94             .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
95             .is_ok();
96 
97         // 如果加锁失败恢复自旋锁持有计数
98         if res == false {
99             preempt_enable();
100         }
101         return res;
102     }
103 
104     /// @brief 解锁
105     pub fn unlock(&self) {
106         // 减少自旋锁持有计数
107         preempt_enable();
108         self.0.store(false, Ordering::Release);
109     }
110 
111     /// @brief 放锁并开中断
112     pub fn unlock_irq(&self) {
113         self.unlock();
114         sti();
115     }
116 
117     /// @brief 判断自旋锁是否被上锁
118     ///
119     /// @return true 自旋锁被上锁
120     /// @return false 自旋锁处于解锁状态
121     pub fn is_locked(&self) -> bool {
122         return self.0.load(Ordering::Relaxed).into();
123     }
124 
125     /// @brief 强制设置自旋锁的状态
126     /// 请注意,这样操作可能会带来未知的风险。因此它是unsafe的。(尽管从Rust语言本身来说,它是safe的)
127     pub unsafe fn set_value(&mut self, value: bool) {
128         self.0.store(value, Ordering::SeqCst);
129     }
130 
131     /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁
132     pub fn lock_irqsave(&self, flags: &mut u64) {
133         local_irq_save(flags);
134         self.lock();
135     }
136 
137     /// @brief 恢复rflags以及中断状态并解锁自旋锁
138     pub fn unlock_irqrestore(&self, flags: &u64) {
139         self.unlock();
140         local_irq_restore(flags);
141     }
142 
143     /// @brief 尝试保存中断状态到flags中,关闭中断,并对自旋锁加锁
144     /// @return 加锁成功->true
145     ///         加锁失败->false
146     #[inline(always)]
147     pub fn try_lock_irqsave(&self, flags: &mut u64) -> bool {
148         local_irq_save(flags);
149         if self.try_lock() {
150             return true;
151         }
152         local_irq_restore(flags);
153         return false;
154     }
155 }
156 /// 实现了守卫的SpinLock, 能够支持内部可变性
157 ///
158 #[derive(Debug)]
159 pub struct SpinLock<T> {
160     lock: RawSpinlock,
161     /// 自旋锁保护的数据
162     data: UnsafeCell<T>,
163 }
164 
165 /// SpinLock的守卫
166 /// 该守卫没有构造器,并且其信息均为私有的。我们只能通过SpinLock的lock()方法获得一个守卫。
167 /// 因此我们可以认为,只要能够获得一个守卫,那么数据就在自旋锁的保护之下。
168 #[derive(Debug)]
169 pub struct SpinLockGuard<'a, T: 'a> {
170     lock: &'a SpinLock<T>,
171     flag: u64,
172 }
173 
174 /// 向编译器保证,SpinLock在线程之间是安全的.
175 /// 其中要求类型T实现了Send这个Trait
176 unsafe impl<T> Sync for SpinLock<T> where T: Send {}
177 
178 impl<T> SpinLock<T> {
179     pub const fn new(value: T) -> Self {
180         return Self {
181             lock: RawSpinlock::INIT,
182             data: UnsafeCell::new(value),
183         };
184     }
185 
186     #[inline(always)]
187     pub fn lock(&self) -> SpinLockGuard<T> {
188         self.lock.lock();
189         // 加锁成功,返回一个守卫
190         return SpinLockGuard {
191             lock: self,
192             flag: 0,
193         };
194     }
195 
196     pub fn lock_irqsave(&self) -> SpinLockGuard<T> {
197         let mut flags: u64 = 0;
198         self.lock.lock_irqsave(&mut flags);
199         // 加锁成功,返回一个守卫
200         return SpinLockGuard {
201             lock: self,
202             flag: flags,
203         };
204     }
205 
206     pub fn try_lock(&self) -> Result<SpinLockGuard<T>, SystemError> {
207         if self.lock.try_lock() {
208             return Ok(SpinLockGuard {
209                 lock: self,
210                 flag: 0,
211             });
212         }
213         return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
214     }
215 
216     pub fn try_lock_irqsave(&self) -> Result<SpinLockGuard<T>, SystemError> {
217         let mut flags: u64 = 0;
218         if self.lock.try_lock_irqsave(&mut flags) {
219             return Ok(SpinLockGuard {
220                 lock: self,
221                 flag: flags,
222             });
223         }
224         return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
225     }
226 }
227 
228 /// 实现Deref trait,支持通过获取SpinLockGuard来获取临界区数据的不可变引用
229 impl<T> Deref for SpinLockGuard<'_, T> {
230     type Target = T;
231 
232     fn deref(&self) -> &Self::Target {
233         return unsafe { &*self.lock.data.get() };
234     }
235 }
236 
237 /// 实现DerefMut trait,支持通过获取SpinLockGuard来获取临界区数据的可变引用
238 impl<T> DerefMut for SpinLockGuard<'_, T> {
239     fn deref_mut(&mut self) -> &mut Self::Target {
240         return unsafe { &mut *self.lock.data.get() };
241     }
242 }
243 
244 /// @brief 为SpinLockGuard实现Drop方法,那么,一旦守卫的生命周期结束,就会自动释放自旋锁,避免了忘记放锁的情况
245 impl<T> Drop for SpinLockGuard<'_, T> {
246     fn drop(&mut self) {
247         if self.flag != 0 {
248             self.lock.lock.unlock_irqrestore(&self.flag);
249         } else {
250             self.lock.lock.unlock();
251         }
252     }
253 }
254