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]
spin_lock_irqsave(lock: *mut spinlock_t, flags: &mut u64)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]
spin_unlock_irqrestore(lock: *mut spinlock_t, flags: &u64)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]
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 /// @brief 放锁并开中断
unlock_irq(&self)112 pub fn unlock_irq(&self) {
113 self.unlock();
114 sti();
115 }
116
117 /// @brief 判断自旋锁是否被上锁
118 ///
119 /// @return true 自旋锁被上锁
120 /// @return false 自旋锁处于解锁状态
is_locked(&self) -> bool121 pub fn is_locked(&self) -> bool {
122 return self.0.load(Ordering::Relaxed).into();
123 }
124
125 /// @brief 强制设置自旋锁的状态
126 /// 请注意,这样操作可能会带来未知的风险。因此它是unsafe的。(尽管从Rust语言本身来说,它是safe的)
set_value(&mut self, value: bool)127 pub unsafe fn set_value(&mut self, value: bool) {
128 self.0.store(value, Ordering::SeqCst);
129 }
130
131 /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁
lock_irqsave(&self, flags: &mut u64)132 pub fn lock_irqsave(&self, flags: &mut u64) {
133 local_irq_save(flags);
134 self.lock();
135 }
136
137 /// @brief 恢复rflags以及中断状态并解锁自旋锁
unlock_irqrestore(&self, flags: &u64)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)]
try_lock_irqsave(&self, flags: &mut u64) -> bool147 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> {
new(value: T) -> Self179 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)]
lock(&self) -> SpinLockGuard<T>187 pub fn lock(&self) -> SpinLockGuard<T> {
188 self.lock.lock();
189 // 加锁成功,返回一个守卫
190 return SpinLockGuard {
191 lock: self,
192 flag: 0,
193 };
194 }
195
lock_irqsave(&self) -> SpinLockGuard<T>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
try_lock(&self) -> Result<SpinLockGuard<T>, SystemError>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
try_lock_irqsave(&self) -> Result<SpinLockGuard<T>, SystemError>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
deref(&self) -> &Self::Target232 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> {
deref_mut(&mut self) -> &mut Self::Target239 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> {
drop(&mut self)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