1 #![allow(dead_code)]
2 use core::cell::UnsafeCell;
3 use core::mem::ManuallyDrop;
4 use core::ops::{Deref, DerefMut};
5 use core::ptr::read_volatile;
6
7 use core::sync::atomic::{AtomicBool, Ordering};
8
9 use crate::arch::asm::irqflags::{local_irq_restore, local_irq_save};
10 use crate::arch::interrupt::{cli, sti};
11 use crate::include::bindings::bindings::{spin_lock, spin_unlock, spinlock_t};
12 use crate::process::preempt::{preempt_disable, preempt_enable};
13 use crate::syscall::SystemError;
14
15 /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁
16 #[inline]
spin_lock_irqsave(lock: *mut spinlock_t, flags: &mut usize)17 pub fn spin_lock_irqsave(lock: *mut spinlock_t, flags: &mut usize) {
18 *flags = local_irq_save();
19 unsafe {
20 spin_lock(lock);
21 }
22 }
23
24 /// @brief 恢复rflags以及中断状态并解锁自旋锁
25 #[inline]
spin_unlock_irqrestore(lock: *mut spinlock_t, flags: usize)26 pub fn spin_unlock_irqrestore(lock: *mut spinlock_t, flags: usize) {
27 unsafe {
28 spin_unlock(lock);
29 }
30 local_irq_restore(flags);
31 }
32
33 /// 判断一个自旋锁是否已经被加锁
34 #[inline]
spin_is_locked(lock: &spinlock_t) -> bool35 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 {
default() -> Self42 fn default() -> Self {
43 Self { lock: 1 }
44 }
45 }
46
47 /// @brief 关闭中断并加锁
spin_lock_irq(lock: *mut spinlock_t)48 pub fn spin_lock_irq(lock: *mut spinlock_t) {
49 cli();
50 unsafe {
51 spin_lock(lock);
52 }
53 }
54
55 /// @brief 解锁并开中断
spin_unlock_irq(lock: *mut spinlock_t)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 加锁
lock(&self)75 pub fn lock(&self) {
76 while !self.try_lock() {}
77 }
78
79 /// @brief 关中断并加锁
lock_irq(&self)80 pub fn lock_irq(&self) {
81 cli();
82 self.lock();
83 }
84
85 /// @brief 尝试加锁
86 /// @return 加锁成功->true
87 /// 加锁失败->false
try_lock(&self) -> bool88 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 解锁
unlock(&self)105 pub fn unlock(&self) {
106 // 减少自旋锁持有计数
107 preempt_enable();
108 self.0.store(false, Ordering::Release);
109 }
110
111 /// 解锁,但是不更改preempt count
unlock_no_preempt(&self)112 unsafe fn unlock_no_preempt(&self) {
113 self.0.store(false, Ordering::Release);
114 }
115
116 /// @brief 放锁并开中断
unlock_irq(&self)117 pub fn unlock_irq(&self) {
118 self.unlock();
119 sti();
120 }
121
122 /// @brief 判断自旋锁是否被上锁
123 ///
124 /// @return true 自旋锁被上锁
125 /// @return false 自旋锁处于解锁状态
is_locked(&self) -> bool126 pub fn is_locked(&self) -> bool {
127 return self.0.load(Ordering::Relaxed).into();
128 }
129
130 /// @brief 强制设置自旋锁的状态
131 /// 请注意,这样操作可能会带来未知的风险。因此它是unsafe的。(尽管从Rust语言本身来说,它是safe的)
set_value(&mut self, value: bool)132 pub unsafe fn set_value(&mut self, value: bool) {
133 self.0.store(value, Ordering::SeqCst);
134 }
135
136 /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁
lock_irqsave(&self, flags: &mut usize)137 pub fn lock_irqsave(&self, flags: &mut usize) {
138 *flags = local_irq_save();
139 self.lock();
140 }
141
142 /// @brief 恢复rflags以及中断状态并解锁自旋锁
unlock_irqrestore(&self, flags: usize)143 pub fn unlock_irqrestore(&self, flags: usize) {
144 self.unlock();
145 local_irq_restore(flags);
146 }
147
148 /// @brief 尝试保存中断状态到flags中,关闭中断,并对自旋锁加锁
149 /// @return 加锁成功->true
150 /// 加锁失败->false
151 #[inline(always)]
try_lock_irqsave(&self, flags: &mut usize) -> bool152 pub fn try_lock_irqsave(&self, flags: &mut usize) -> bool {
153 *flags = local_irq_save();
154 if self.try_lock() {
155 return true;
156 }
157 local_irq_restore(*flags);
158 return false;
159 }
160 }
161 /// 实现了守卫的SpinLock, 能够支持内部可变性
162 ///
163 #[derive(Debug)]
164 pub struct SpinLock<T> {
165 lock: RawSpinlock,
166 /// 自旋锁保护的数据
167 data: UnsafeCell<T>,
168 }
169
170 /// SpinLock的守卫
171 /// 该守卫没有构造器,并且其信息均为私有的。我们只能通过SpinLock的lock()方法获得一个守卫。
172 /// 因此我们可以认为,只要能够获得一个守卫,那么数据就在自旋锁的保护之下。
173 #[derive(Debug)]
174 pub struct SpinLockGuard<'a, T: 'a> {
175 lock: &'a SpinLock<T>,
176 flag: usize,
177 }
178
179 impl<'a, T: 'a> SpinLockGuard<'a, T> {
180 /// 泄露自旋锁的守卫,返回一个可变的引用
181 ///
182 /// ## Safety
183 ///
184 /// 由于这样做可能导致守卫在另一个线程中被释放,从而导致pcb的preempt count不正确,
185 /// 因此必须小心的手动维护好preempt count。
186 ///
187 /// 并且,leak还可能导致锁的状态不正确。因此请仔细考虑是否真的需要使用这个函数。
188 #[inline]
leak(this: Self) -> &'a mut T189 pub unsafe fn leak(this: Self) -> &'a mut T {
190 // Use ManuallyDrop to avoid stacked-borrow invalidation
191 let this = ManuallyDrop::new(this);
192 // We know statically that only we are referencing data
193 unsafe { &mut *this.lock.data.get() }
194 }
195 }
196
197 /// 向编译器保证,SpinLock在线程之间是安全的.
198 /// 其中要求类型T实现了Send这个Trait
199 unsafe impl<T> Sync for SpinLock<T> where T: Send {}
200
201 impl<T> SpinLock<T> {
new(value: T) -> Self202 pub const fn new(value: T) -> Self {
203 return Self {
204 lock: RawSpinlock::INIT,
205 data: UnsafeCell::new(value),
206 };
207 }
208
209 #[inline(always)]
lock(&self) -> SpinLockGuard<T>210 pub fn lock(&self) -> SpinLockGuard<T> {
211 self.lock.lock();
212 // 加锁成功,返回一个守卫
213 return SpinLockGuard {
214 lock: self,
215 flag: 0,
216 };
217 }
218
lock_irqsave(&self) -> SpinLockGuard<T>219 pub fn lock_irqsave(&self) -> SpinLockGuard<T> {
220 let mut flags: usize = 0;
221
222 self.lock.lock_irqsave(&mut flags);
223 // 加锁成功,返回一个守卫
224 return SpinLockGuard {
225 lock: self,
226 flag: flags,
227 };
228 }
229
try_lock(&self) -> Result<SpinLockGuard<T>, SystemError>230 pub fn try_lock(&self) -> Result<SpinLockGuard<T>, SystemError> {
231 if self.lock.try_lock() {
232 return Ok(SpinLockGuard {
233 lock: self,
234 flag: 0,
235 });
236 }
237 return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
238 }
239
try_lock_irqsave(&self) -> Result<SpinLockGuard<T>, SystemError>240 pub fn try_lock_irqsave(&self) -> Result<SpinLockGuard<T>, SystemError> {
241 let mut flags: usize = 0;
242 if self.lock.try_lock_irqsave(&mut flags) {
243 return Ok(SpinLockGuard {
244 lock: self,
245 flag: flags,
246 });
247 }
248 return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
249 }
250
251 /// 强制解锁,并且不更改preempt count
252 ///
253 /// ## Safety
254 ///
255 /// 由于这样做可能导致preempt count不正确,因此必须小心的手动维护好preempt count。
256 /// 如非必要,请不要使用这个函数。
force_unlock(&self)257 pub unsafe fn force_unlock(&self) {
258 self.lock.unlock_no_preempt();
259 }
260 }
261
262 /// 实现Deref trait,支持通过获取SpinLockGuard来获取临界区数据的不可变引用
263 impl<T> Deref for SpinLockGuard<'_, T> {
264 type Target = T;
265
deref(&self) -> &Self::Target266 fn deref(&self) -> &Self::Target {
267 return unsafe { &*self.lock.data.get() };
268 }
269 }
270
271 /// 实现DerefMut trait,支持通过获取SpinLockGuard来获取临界区数据的可变引用
272 impl<T> DerefMut for SpinLockGuard<'_, T> {
deref_mut(&mut self) -> &mut Self::Target273 fn deref_mut(&mut self) -> &mut Self::Target {
274 return unsafe { &mut *self.lock.data.get() };
275 }
276 }
277
278 /// @brief 为SpinLockGuard实现Drop方法,那么,一旦守卫的生命周期结束,就会自动释放自旋锁,避免了忘记放锁的情况
279 impl<T> Drop for SpinLockGuard<'_, T> {
drop(&mut self)280 fn drop(&mut self) {
281 if self.flag != 0 {
282 self.lock.lock.unlock_irqrestore(self.flag);
283 } else {
284 self.lock.lock.unlock();
285 }
286 }
287 }
288