166f67c6aSlogin #![allow(dead_code)] 2ec53d23eSlogin use core::cell::UnsafeCell; 31496ba7bSLoGin 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 91496ba7bSLoGin use crate::arch::CurrentIrqArch; 101496ba7bSLoGin use crate::exception::{InterruptArch, IrqFlagsGuard}; 111496ba7bSLoGin use crate::process::ProcessManager; 1291e9d4abSLoGin use system_error::SystemError; 1366f67c6aSlogin 14ec53d23eSlogin /// 实现了守卫的SpinLock, 能够支持内部可变性 15ec53d23eSlogin /// 16ec53d23eSlogin #[derive(Debug)] 17ec53d23eSlogin pub struct SpinLock<T> { 181496ba7bSLoGin 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>, 297ae679ddSLoGin data: *mut T, 301496ba7bSLoGin irq_flag: Option<IrqFlagsGuard>, 311496ba7bSLoGin flags: SpinLockGuardFlags, 32ec53d23eSlogin } 33ec53d23eSlogin 3490a0a490SLoGin impl<'a, T: 'a> SpinLockGuard<'a, T> { 3590a0a490SLoGin /// 泄露自旋锁的守卫,返回一个可变的引用 3690a0a490SLoGin /// 3790a0a490SLoGin /// ## Safety 3890a0a490SLoGin /// 3990a0a490SLoGin /// 由于这样做可能导致守卫在另一个线程中被释放,从而导致pcb的preempt count不正确, 4090a0a490SLoGin /// 因此必须小心的手动维护好preempt count。 4190a0a490SLoGin /// 4290a0a490SLoGin /// 并且,leak还可能导致锁的状态不正确。因此请仔细考虑是否真的需要使用这个函数。 4390a0a490SLoGin #[inline] leak(this: Self) -> &'a mut T4490a0a490SLoGin pub unsafe fn leak(this: Self) -> &'a mut T { 4590a0a490SLoGin // Use ManuallyDrop to avoid stacked-borrow invalidation 4690a0a490SLoGin let this = ManuallyDrop::new(this); 4790a0a490SLoGin // We know statically that only we are referencing data 4890a0a490SLoGin unsafe { &mut *this.lock.data.get() } 4990a0a490SLoGin } 501496ba7bSLoGin unlock_no_preempt(&self)511496ba7bSLoGin fn unlock_no_preempt(&self) { 521496ba7bSLoGin unsafe { 531496ba7bSLoGin self.lock.force_unlock(); 541496ba7bSLoGin } 551496ba7bSLoGin } 5690a0a490SLoGin } 5790a0a490SLoGin 58ec53d23eSlogin /// 向编译器保证,SpinLock在线程之间是安全的. 59ec53d23eSlogin /// 其中要求类型T实现了Send这个Trait 60ec53d23eSlogin unsafe impl<T> Sync for SpinLock<T> where T: Send {} 61ec53d23eSlogin 62ec53d23eSlogin impl<T> SpinLock<T> { new(value: T) -> Self63ec53d23eSlogin pub const fn new(value: T) -> Self { 64ec53d23eSlogin return Self { 651496ba7bSLoGin lock: AtomicBool::new(false), 66ec53d23eSlogin data: UnsafeCell::new(value), 67ec53d23eSlogin }; 68ec53d23eSlogin } 69ec53d23eSlogin 70ec53d23eSlogin #[inline(always)] lock(&self) -> SpinLockGuard<T>71ec53d23eSlogin pub fn lock(&self) -> SpinLockGuard<T> { 721496ba7bSLoGin loop { 731496ba7bSLoGin let res = self.try_lock(); 74b5b571e0SLoGin if let Ok(res) = res { 75b5b571e0SLoGin return res; 761496ba7bSLoGin } 771496ba7bSLoGin spin_loop(); 781496ba7bSLoGin } 791496ba7bSLoGin } 801496ba7bSLoGin 811496ba7bSLoGin /// 加锁,但是不更改preempt count 821496ba7bSLoGin #[inline(always)] lock_no_preempt(&self) -> SpinLockGuard<T>831496ba7bSLoGin pub fn lock_no_preempt(&self) -> SpinLockGuard<T> { 841496ba7bSLoGin loop { 851496ba7bSLoGin if let Ok(guard) = self.try_lock_no_preempt() { 861496ba7bSLoGin return guard; 871496ba7bSLoGin } 881496ba7bSLoGin spin_loop(); 891496ba7bSLoGin } 90bacd691cSlogin } 91bacd691cSlogin lock_irqsave(&self) -> SpinLockGuard<T>92bacd691cSlogin pub fn lock_irqsave(&self) -> SpinLockGuard<T> { 931496ba7bSLoGin loop { 941496ba7bSLoGin if let Ok(guard) = self.try_lock_irqsave() { 951496ba7bSLoGin return guard; 961496ba7bSLoGin } 971496ba7bSLoGin spin_loop(); 981496ba7bSLoGin } 99bacd691cSlogin } 100bacd691cSlogin try_lock(&self) -> Result<SpinLockGuard<T>, SystemError>101bacd691cSlogin pub fn try_lock(&self) -> Result<SpinLockGuard<T>, SystemError> { 1021496ba7bSLoGin // 先增加自旋锁持有计数 1031496ba7bSLoGin ProcessManager::preempt_disable(); 1041496ba7bSLoGin 1051496ba7bSLoGin if self.inner_try_lock() { 106bacd691cSlogin return Ok(SpinLockGuard { 107bacd691cSlogin lock: self, 1087ae679ddSLoGin data: unsafe { &mut *self.data.get() }, 1091496ba7bSLoGin irq_flag: None, 1101496ba7bSLoGin flags: SpinLockGuardFlags::empty(), 111bacd691cSlogin }); 112bacd691cSlogin } 1131496ba7bSLoGin 1141496ba7bSLoGin // 如果加锁失败恢复自旋锁持有计数 1151496ba7bSLoGin ProcessManager::preempt_enable(); 1161496ba7bSLoGin 11779a452ceShoumkh return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 118bacd691cSlogin } 119bacd691cSlogin inner_try_lock(&self) -> bool1201496ba7bSLoGin fn inner_try_lock(&self) -> bool { 1211496ba7bSLoGin let res = self 1221496ba7bSLoGin .lock 1237ae679ddSLoGin .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst) 1241496ba7bSLoGin .is_ok(); 1251496ba7bSLoGin return res; 1261496ba7bSLoGin } 1271496ba7bSLoGin try_lock_irqsave(&self) -> Result<SpinLockGuard<T>, SystemError>128bacd691cSlogin pub fn try_lock_irqsave(&self) -> Result<SpinLockGuard<T>, SystemError> { 1291496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1301496ba7bSLoGin ProcessManager::preempt_disable(); 1311496ba7bSLoGin if self.inner_try_lock() { 132bacd691cSlogin return Ok(SpinLockGuard { 133bacd691cSlogin lock: self, 1347ae679ddSLoGin data: unsafe { &mut *self.data.get() }, 1351496ba7bSLoGin irq_flag: Some(irq_guard), 1361496ba7bSLoGin flags: SpinLockGuardFlags::empty(), 1371496ba7bSLoGin }); 1381496ba7bSLoGin } 1391496ba7bSLoGin ProcessManager::preempt_enable(); 1401496ba7bSLoGin drop(irq_guard); 1411496ba7bSLoGin return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 1421496ba7bSLoGin } 1431496ba7bSLoGin try_lock_no_preempt(&self) -> Result<SpinLockGuard<T>, SystemError>1441496ba7bSLoGin pub fn try_lock_no_preempt(&self) -> Result<SpinLockGuard<T>, SystemError> { 1451496ba7bSLoGin if self.inner_try_lock() { 1461496ba7bSLoGin return Ok(SpinLockGuard { 1471496ba7bSLoGin lock: self, 1487ae679ddSLoGin data: unsafe { &mut *self.data.get() }, 1491496ba7bSLoGin irq_flag: None, 1501496ba7bSLoGin flags: SpinLockGuardFlags::NO_PREEMPT, 151bacd691cSlogin }); 152bacd691cSlogin } 15379a452ceShoumkh return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 154ec53d23eSlogin } 15590a0a490SLoGin 15690a0a490SLoGin /// 强制解锁,并且不更改preempt count 15790a0a490SLoGin /// 15890a0a490SLoGin /// ## Safety 15990a0a490SLoGin /// 16090a0a490SLoGin /// 由于这样做可能导致preempt count不正确,因此必须小心的手动维护好preempt count。 16190a0a490SLoGin /// 如非必要,请不要使用这个函数。 force_unlock(&self)16290a0a490SLoGin pub unsafe fn force_unlock(&self) { 1637ae679ddSLoGin self.lock.store(false, Ordering::SeqCst); 1641496ba7bSLoGin } 1651496ba7bSLoGin unlock(&self)1661496ba7bSLoGin fn unlock(&self) { 1677ae679ddSLoGin self.lock.store(false, Ordering::SeqCst); 1681496ba7bSLoGin ProcessManager::preempt_enable(); 16990a0a490SLoGin } 170*f0c87a89SGnoCiYeH is_locked(&self) -> bool171*f0c87a89SGnoCiYeH pub fn is_locked(&self) -> bool { 172*f0c87a89SGnoCiYeH self.lock.load(Ordering::SeqCst) 173*f0c87a89SGnoCiYeH } 174ec53d23eSlogin } 175ec53d23eSlogin 176ec53d23eSlogin /// 实现Deref trait,支持通过获取SpinLockGuard来获取临界区数据的不可变引用 177ec53d23eSlogin impl<T> Deref for SpinLockGuard<'_, T> { 178ec53d23eSlogin type Target = T; 179ec53d23eSlogin deref(&self) -> &Self::Target180ec53d23eSlogin fn deref(&self) -> &Self::Target { 1817ae679ddSLoGin return unsafe { &*self.data }; 182ec53d23eSlogin } 183ec53d23eSlogin } 184ec53d23eSlogin 185ec53d23eSlogin /// 实现DerefMut trait,支持通过获取SpinLockGuard来获取临界区数据的可变引用 186ec53d23eSlogin impl<T> DerefMut for SpinLockGuard<'_, T> { deref_mut(&mut self) -> &mut Self::Target187ec53d23eSlogin fn deref_mut(&mut self) -> &mut Self::Target { 1887ae679ddSLoGin return unsafe { &mut *self.data }; 189ec53d23eSlogin } 190ec53d23eSlogin } 191ec53d23eSlogin 192ec53d23eSlogin /// @brief 为SpinLockGuard实现Drop方法,那么,一旦守卫的生命周期结束,就会自动释放自旋锁,避免了忘记放锁的情况 193ec53d23eSlogin impl<T> Drop for SpinLockGuard<'_, T> { drop(&mut self)194ec53d23eSlogin fn drop(&mut self) { 1951496ba7bSLoGin if self.flags.contains(SpinLockGuardFlags::NO_PREEMPT) { 1961496ba7bSLoGin self.unlock_no_preempt(); 197cde5492fSlogin } else { 1981496ba7bSLoGin self.lock.unlock(); 199ec53d23eSlogin } 2001496ba7bSLoGin // restore irq 2011496ba7bSLoGin self.irq_flag.take(); 2021496ba7bSLoGin } 2031496ba7bSLoGin } 2041496ba7bSLoGin 2051496ba7bSLoGin bitflags! { 2061496ba7bSLoGin struct SpinLockGuardFlags: u8 { 2071496ba7bSLoGin /// 守卫是由“*no_preempt”方法获得的 2081496ba7bSLoGin const NO_PREEMPT = (1<<0); 209ac643d42Slogin } 210cde5492fSlogin } 211