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] 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] 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] 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 /// 解锁,但是不更改preempt count 112 unsafe fn unlock_no_preempt(&self) { 113 self.0.store(false, Ordering::Release); 114 } 115 116 /// @brief 放锁并开中断 117 pub fn unlock_irq(&self) { 118 self.unlock(); 119 sti(); 120 } 121 122 /// @brief 判断自旋锁是否被上锁 123 /// 124 /// @return true 自旋锁被上锁 125 /// @return false 自旋锁处于解锁状态 126 pub fn is_locked(&self) -> bool { 127 return self.0.load(Ordering::Relaxed).into(); 128 } 129 130 /// @brief 强制设置自旋锁的状态 131 /// 请注意,这样操作可能会带来未知的风险。因此它是unsafe的。(尽管从Rust语言本身来说,它是safe的) 132 pub unsafe fn set_value(&mut self, value: bool) { 133 self.0.store(value, Ordering::SeqCst); 134 } 135 136 /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁 137 pub fn lock_irqsave(&self, flags: &mut usize) { 138 *flags = local_irq_save(); 139 self.lock(); 140 } 141 142 /// @brief 恢复rflags以及中断状态并解锁自旋锁 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)] 152 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] 189 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> { 202 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)] 210 pub fn lock(&self) -> SpinLockGuard<T> { 211 self.lock.lock(); 212 // 加锁成功,返回一个守卫 213 return SpinLockGuard { 214 lock: self, 215 flag: 0, 216 }; 217 } 218 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 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 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 /// 如非必要,请不要使用这个函数。 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 266 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> { 273 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> { 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