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