166f67c6aSlogin #![allow(dead_code)] 2ec53d23eSlogin use core::cell::UnsafeCell; 3*1496ba7bSLoGin use core::hint::spin_loop; 490a0a490SLoGin use core::mem::ManuallyDrop; 5ec53d23eSlogin use core::ops::{Deref, DerefMut}; 666f67c6aSlogin 7ac643d42Slogin use core::sync::atomic::{AtomicBool, Ordering}; 8ac643d42Slogin 9*1496ba7bSLoGin use crate::arch::CurrentIrqArch; 10*1496ba7bSLoGin use crate::exception::{InterruptArch, IrqFlagsGuard}; 11*1496ba7bSLoGin use crate::process::ProcessManager; 12bacd691cSlogin use crate::syscall::SystemError; 1366f67c6aSlogin 14ec53d23eSlogin /// 实现了守卫的SpinLock, 能够支持内部可变性 15ec53d23eSlogin /// 16ec53d23eSlogin #[derive(Debug)] 17ec53d23eSlogin pub struct SpinLock<T> { 18*1496ba7bSLoGin lock: AtomicBool, 19ec53d23eSlogin /// 自旋锁保护的数据 20ec53d23eSlogin data: UnsafeCell<T>, 21ec53d23eSlogin } 22ec53d23eSlogin 23ec53d23eSlogin /// SpinLock的守卫 24ec53d23eSlogin /// 该守卫没有构造器,并且其信息均为私有的。我们只能通过SpinLock的lock()方法获得一个守卫。 25ec53d23eSlogin /// 因此我们可以认为,只要能够获得一个守卫,那么数据就在自旋锁的保护之下。 26ec53d23eSlogin #[derive(Debug)] 27ec53d23eSlogin pub struct SpinLockGuard<'a, T: 'a> { 28ec53d23eSlogin lock: &'a SpinLock<T>, 29*1496ba7bSLoGin irq_flag: Option<IrqFlagsGuard>, 30*1496ba7bSLoGin flags: SpinLockGuardFlags, 31ec53d23eSlogin } 32ec53d23eSlogin 3390a0a490SLoGin impl<'a, T: 'a> SpinLockGuard<'a, T> { 3490a0a490SLoGin /// 泄露自旋锁的守卫,返回一个可变的引用 3590a0a490SLoGin /// 3690a0a490SLoGin /// ## Safety 3790a0a490SLoGin /// 3890a0a490SLoGin /// 由于这样做可能导致守卫在另一个线程中被释放,从而导致pcb的preempt count不正确, 3990a0a490SLoGin /// 因此必须小心的手动维护好preempt count。 4090a0a490SLoGin /// 4190a0a490SLoGin /// 并且,leak还可能导致锁的状态不正确。因此请仔细考虑是否真的需要使用这个函数。 4290a0a490SLoGin #[inline] 4390a0a490SLoGin pub unsafe fn leak(this: Self) -> &'a mut T { 4490a0a490SLoGin // Use ManuallyDrop to avoid stacked-borrow invalidation 4590a0a490SLoGin let this = ManuallyDrop::new(this); 4690a0a490SLoGin // We know statically that only we are referencing data 4790a0a490SLoGin unsafe { &mut *this.lock.data.get() } 4890a0a490SLoGin } 49*1496ba7bSLoGin 50*1496ba7bSLoGin fn unlock_no_preempt(&self) { 51*1496ba7bSLoGin unsafe { 52*1496ba7bSLoGin self.lock.force_unlock(); 53*1496ba7bSLoGin } 54*1496ba7bSLoGin } 5590a0a490SLoGin } 5690a0a490SLoGin 57ec53d23eSlogin /// 向编译器保证,SpinLock在线程之间是安全的. 58ec53d23eSlogin /// 其中要求类型T实现了Send这个Trait 59ec53d23eSlogin unsafe impl<T> Sync for SpinLock<T> where T: Send {} 60ec53d23eSlogin 61ec53d23eSlogin impl<T> SpinLock<T> { 62ec53d23eSlogin pub const fn new(value: T) -> Self { 63ec53d23eSlogin return Self { 64*1496ba7bSLoGin lock: AtomicBool::new(false), 65ec53d23eSlogin data: UnsafeCell::new(value), 66ec53d23eSlogin }; 67ec53d23eSlogin } 68ec53d23eSlogin 69ec53d23eSlogin #[inline(always)] 70ec53d23eSlogin pub fn lock(&self) -> SpinLockGuard<T> { 71*1496ba7bSLoGin loop { 72*1496ba7bSLoGin let res = self.try_lock(); 73*1496ba7bSLoGin if res.is_ok() { 74*1496ba7bSLoGin return res.unwrap(); 75*1496ba7bSLoGin } 76*1496ba7bSLoGin spin_loop(); 77*1496ba7bSLoGin } 78*1496ba7bSLoGin } 79*1496ba7bSLoGin 80*1496ba7bSLoGin /// 加锁,但是不更改preempt count 81*1496ba7bSLoGin #[inline(always)] 82*1496ba7bSLoGin pub fn lock_no_preempt(&self) -> SpinLockGuard<T> { 83*1496ba7bSLoGin loop { 84*1496ba7bSLoGin if let Ok(guard) = self.try_lock_no_preempt() { 85*1496ba7bSLoGin return guard; 86*1496ba7bSLoGin } 87*1496ba7bSLoGin spin_loop(); 88*1496ba7bSLoGin } 89bacd691cSlogin } 90bacd691cSlogin 91bacd691cSlogin pub fn lock_irqsave(&self) -> SpinLockGuard<T> { 92*1496ba7bSLoGin loop { 93*1496ba7bSLoGin if let Ok(guard) = self.try_lock_irqsave() { 94*1496ba7bSLoGin return guard; 95*1496ba7bSLoGin } 96*1496ba7bSLoGin spin_loop(); 97*1496ba7bSLoGin } 98bacd691cSlogin } 99bacd691cSlogin 100bacd691cSlogin pub fn try_lock(&self) -> Result<SpinLockGuard<T>, SystemError> { 101*1496ba7bSLoGin // 先增加自旋锁持有计数 102*1496ba7bSLoGin ProcessManager::preempt_disable(); 103*1496ba7bSLoGin 104*1496ba7bSLoGin if self.inner_try_lock() { 105bacd691cSlogin return Ok(SpinLockGuard { 106bacd691cSlogin lock: self, 107*1496ba7bSLoGin irq_flag: None, 108*1496ba7bSLoGin flags: SpinLockGuardFlags::empty(), 109bacd691cSlogin }); 110bacd691cSlogin } 111*1496ba7bSLoGin 112*1496ba7bSLoGin // 如果加锁失败恢复自旋锁持有计数 113*1496ba7bSLoGin ProcessManager::preempt_enable(); 114*1496ba7bSLoGin 11579a452ceShoumkh return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 116bacd691cSlogin } 117bacd691cSlogin 118*1496ba7bSLoGin fn inner_try_lock(&self) -> bool { 119*1496ba7bSLoGin let res = self 120*1496ba7bSLoGin .lock 121*1496ba7bSLoGin .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) 122*1496ba7bSLoGin .is_ok(); 123*1496ba7bSLoGin return res; 124*1496ba7bSLoGin } 125*1496ba7bSLoGin 126bacd691cSlogin pub fn try_lock_irqsave(&self) -> Result<SpinLockGuard<T>, SystemError> { 127*1496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 128*1496ba7bSLoGin ProcessManager::preempt_disable(); 129*1496ba7bSLoGin if self.inner_try_lock() { 130bacd691cSlogin return Ok(SpinLockGuard { 131bacd691cSlogin lock: self, 132*1496ba7bSLoGin irq_flag: Some(irq_guard), 133*1496ba7bSLoGin flags: SpinLockGuardFlags::empty(), 134*1496ba7bSLoGin }); 135*1496ba7bSLoGin } 136*1496ba7bSLoGin ProcessManager::preempt_enable(); 137*1496ba7bSLoGin drop(irq_guard); 138*1496ba7bSLoGin return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 139*1496ba7bSLoGin } 140*1496ba7bSLoGin 141*1496ba7bSLoGin pub fn try_lock_no_preempt(&self) -> Result<SpinLockGuard<T>, SystemError> { 142*1496ba7bSLoGin if self.inner_try_lock() { 143*1496ba7bSLoGin return Ok(SpinLockGuard { 144*1496ba7bSLoGin lock: self, 145*1496ba7bSLoGin irq_flag: None, 146*1496ba7bSLoGin flags: SpinLockGuardFlags::NO_PREEMPT, 147bacd691cSlogin }); 148bacd691cSlogin } 14979a452ceShoumkh return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 150ec53d23eSlogin } 15190a0a490SLoGin 15290a0a490SLoGin /// 强制解锁,并且不更改preempt count 15390a0a490SLoGin /// 15490a0a490SLoGin /// ## Safety 15590a0a490SLoGin /// 15690a0a490SLoGin /// 由于这样做可能导致preempt count不正确,因此必须小心的手动维护好preempt count。 15790a0a490SLoGin /// 如非必要,请不要使用这个函数。 15890a0a490SLoGin pub unsafe fn force_unlock(&self) { 159*1496ba7bSLoGin self.lock.store(false, Ordering::Release); 160*1496ba7bSLoGin } 161*1496ba7bSLoGin 162*1496ba7bSLoGin fn unlock(&self) { 163*1496ba7bSLoGin self.lock.store(false, Ordering::Release); 164*1496ba7bSLoGin ProcessManager::preempt_enable(); 16590a0a490SLoGin } 166ec53d23eSlogin } 167ec53d23eSlogin 168ec53d23eSlogin /// 实现Deref trait,支持通过获取SpinLockGuard来获取临界区数据的不可变引用 169ec53d23eSlogin impl<T> Deref for SpinLockGuard<'_, T> { 170ec53d23eSlogin type Target = T; 171ec53d23eSlogin 172ec53d23eSlogin fn deref(&self) -> &Self::Target { 173ec53d23eSlogin return unsafe { &*self.lock.data.get() }; 174ec53d23eSlogin } 175ec53d23eSlogin } 176ec53d23eSlogin 177ec53d23eSlogin /// 实现DerefMut trait,支持通过获取SpinLockGuard来获取临界区数据的可变引用 178ec53d23eSlogin impl<T> DerefMut for SpinLockGuard<'_, T> { 179ec53d23eSlogin fn deref_mut(&mut self) -> &mut Self::Target { 180ec53d23eSlogin return unsafe { &mut *self.lock.data.get() }; 181ec53d23eSlogin } 182ec53d23eSlogin } 183ec53d23eSlogin 184ec53d23eSlogin /// @brief 为SpinLockGuard实现Drop方法,那么,一旦守卫的生命周期结束,就会自动释放自旋锁,避免了忘记放锁的情况 185ec53d23eSlogin impl<T> Drop for SpinLockGuard<'_, T> { 186ec53d23eSlogin fn drop(&mut self) { 187*1496ba7bSLoGin if self.flags.contains(SpinLockGuardFlags::NO_PREEMPT) { 188*1496ba7bSLoGin self.unlock_no_preempt(); 189cde5492fSlogin } else { 190*1496ba7bSLoGin self.lock.unlock(); 191ec53d23eSlogin } 192*1496ba7bSLoGin // restore irq 193*1496ba7bSLoGin self.irq_flag.take(); 194*1496ba7bSLoGin } 195*1496ba7bSLoGin } 196*1496ba7bSLoGin 197*1496ba7bSLoGin bitflags! { 198*1496ba7bSLoGin struct SpinLockGuardFlags: u8 { 199*1496ba7bSLoGin /// 守卫是由“*no_preempt”方法获得的 200*1496ba7bSLoGin const NO_PREEMPT = (1<<0); 201ac643d42Slogin } 202cde5492fSlogin } 203