166f67c6aSlogin #![allow(dead_code)] 2ec53d23eSlogin use core::cell::UnsafeCell; 3*90a0a490SLoGin use core::mem::ManuallyDrop; 4ec53d23eSlogin use core::ops::{Deref, DerefMut}; 566f67c6aSlogin use core::ptr::read_volatile; 666f67c6aSlogin 7ac643d42Slogin use core::sync::atomic::{AtomicBool, Ordering}; 8ac643d42Slogin 9adc1846bSlogin use crate::arch::asm::irqflags::{local_irq_restore, local_irq_save}; 10adc1846bSlogin use crate::arch::interrupt::{cli, sti}; 1166f67c6aSlogin use crate::include::bindings::bindings::{spin_lock, spin_unlock, spinlock_t}; 12ac643d42Slogin use crate::process::preempt::{preempt_disable, preempt_enable}; 13bacd691cSlogin use crate::syscall::SystemError; 1466f67c6aSlogin 1566f67c6aSlogin /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁 161a2eaa40Slogin #[inline] 1740fe15e0SLoGin pub fn spin_lock_irqsave(lock: *mut spinlock_t, flags: &mut usize) { 1840fe15e0SLoGin *flags = local_irq_save(); 1966f67c6aSlogin unsafe { 2066f67c6aSlogin spin_lock(lock); 2166f67c6aSlogin } 2266f67c6aSlogin } 2366f67c6aSlogin 2466f67c6aSlogin /// @brief 恢复rflags以及中断状态并解锁自旋锁 251a2eaa40Slogin #[inline] 2640fe15e0SLoGin pub fn spin_unlock_irqrestore(lock: *mut spinlock_t, flags: usize) { 2766f67c6aSlogin unsafe { 2866f67c6aSlogin spin_unlock(lock); 2966f67c6aSlogin } 3040fe15e0SLoGin local_irq_restore(flags); 3166f67c6aSlogin } 3266f67c6aSlogin 3366f67c6aSlogin /// 判断一个自旋锁是否已经被加锁 341a2eaa40Slogin #[inline] 3566f67c6aSlogin pub fn spin_is_locked(lock: &spinlock_t) -> bool { 3666f67c6aSlogin let val = unsafe { read_volatile(&lock.lock as *const i8) }; 3766f67c6aSlogin 3866f67c6aSlogin return if val == 0 { true } else { false }; 3966f67c6aSlogin } 40c8025a88Slogin 41c8025a88Slogin impl Default for spinlock_t { 42c8025a88Slogin fn default() -> Self { 43c8025a88Slogin Self { lock: 1 } 44c8025a88Slogin } 45c8025a88Slogin } 461a2eaa40Slogin 471a2eaa40Slogin /// @brief 关闭中断并加锁 481a2eaa40Slogin pub fn spin_lock_irq(lock: *mut spinlock_t) { 491a2eaa40Slogin cli(); 50ac643d42Slogin unsafe { 51ac643d42Slogin spin_lock(lock); 52ac643d42Slogin } 531a2eaa40Slogin } 541a2eaa40Slogin 551a2eaa40Slogin /// @brief 解锁并开中断 561a2eaa40Slogin pub fn spin_unlock_irq(lock: *mut spinlock_t) { 57ac643d42Slogin unsafe { 58ac643d42Slogin spin_unlock(lock); 59ac643d42Slogin } 601a2eaa40Slogin sti(); 611a2eaa40Slogin } 62ac643d42Slogin 6361de2cdcSlogin /// 原始的Spinlock(自旋锁) 6461de2cdcSlogin /// 请注意,这个自旋锁和C的不兼容。 6561de2cdcSlogin /// 6661de2cdcSlogin /// @param self.0 这个AtomicBool的值为false时,表示没有被加锁。当它为true时,表示自旋锁已经被上锁。 67d4f3de93Slogin #[derive(Debug)] 68ac643d42Slogin pub struct RawSpinlock(AtomicBool); 69ac643d42Slogin 70ac643d42Slogin impl RawSpinlock { 71ac643d42Slogin /// @brief 初始化自旋锁 72d4f3de93Slogin pub const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false)); 73ac643d42Slogin 74ac643d42Slogin /// @brief 加锁 75ec53d23eSlogin pub fn lock(&self) { 76ac643d42Slogin while !self.try_lock() {} 77ac643d42Slogin } 78ac643d42Slogin 79ac643d42Slogin /// @brief 关中断并加锁 80ec53d23eSlogin pub fn lock_irq(&self) { 81ac643d42Slogin cli(); 82ac643d42Slogin self.lock(); 83ac643d42Slogin } 84ac643d42Slogin 85ac643d42Slogin /// @brief 尝试加锁 86ac643d42Slogin /// @return 加锁成功->true 87ac643d42Slogin /// 加锁失败->false 88ec53d23eSlogin pub fn try_lock(&self) -> bool { 89ac643d42Slogin // 先增加自旋锁持有计数 90ac643d42Slogin preempt_disable(); 91ac643d42Slogin 92ac643d42Slogin let res = self 93ac643d42Slogin .0 94ac643d42Slogin .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) 95ac643d42Slogin .is_ok(); 96ac643d42Slogin 97ac643d42Slogin // 如果加锁失败恢复自旋锁持有计数 98ac643d42Slogin if res == false { 99ac643d42Slogin preempt_enable(); 100ac643d42Slogin } 101ac643d42Slogin return res; 102ac643d42Slogin } 103ac643d42Slogin 104ac643d42Slogin /// @brief 解锁 105ec53d23eSlogin pub fn unlock(&self) { 106ac643d42Slogin // 减少自旋锁持有计数 107ac643d42Slogin preempt_enable(); 108ac643d42Slogin self.0.store(false, Ordering::Release); 109ac643d42Slogin } 110ac643d42Slogin 111*90a0a490SLoGin /// 解锁,但是不更改preempt count 112*90a0a490SLoGin unsafe fn unlock_no_preempt(&self) { 113*90a0a490SLoGin self.0.store(false, Ordering::Release); 114*90a0a490SLoGin } 115*90a0a490SLoGin 116ac643d42Slogin /// @brief 放锁并开中断 117ec53d23eSlogin pub fn unlock_irq(&self) { 118ac643d42Slogin self.unlock(); 119ac643d42Slogin sti(); 120ac643d42Slogin } 121ac643d42Slogin 12261de2cdcSlogin /// @brief 判断自旋锁是否被上锁 12361de2cdcSlogin /// 12461de2cdcSlogin /// @return true 自旋锁被上锁 12561de2cdcSlogin /// @return false 自旋锁处于解锁状态 126ec53d23eSlogin pub fn is_locked(&self) -> bool { 12761de2cdcSlogin return self.0.load(Ordering::Relaxed).into(); 12861de2cdcSlogin } 12961de2cdcSlogin 13061de2cdcSlogin /// @brief 强制设置自旋锁的状态 13161de2cdcSlogin /// 请注意,这样操作可能会带来未知的风险。因此它是unsafe的。(尽管从Rust语言本身来说,它是safe的) 13261de2cdcSlogin pub unsafe fn set_value(&mut self, value: bool) { 13361de2cdcSlogin self.0.store(value, Ordering::SeqCst); 13461de2cdcSlogin } 13561de2cdcSlogin 136d8a06412SGou Ngai /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁 13740fe15e0SLoGin pub fn lock_irqsave(&self, flags: &mut usize) { 13840fe15e0SLoGin *flags = local_irq_save(); 139d8a06412SGou Ngai self.lock(); 140ec53d23eSlogin } 141ac643d42Slogin 142d8a06412SGou Ngai /// @brief 恢复rflags以及中断状态并解锁自旋锁 14340fe15e0SLoGin pub fn unlock_irqrestore(&self, flags: usize) { 144d8a06412SGou Ngai self.unlock(); 14540fe15e0SLoGin local_irq_restore(flags); 146d8a06412SGou Ngai } 147bacd691cSlogin 148bacd691cSlogin /// @brief 尝试保存中断状态到flags中,关闭中断,并对自旋锁加锁 149bacd691cSlogin /// @return 加锁成功->true 150bacd691cSlogin /// 加锁失败->false 151bacd691cSlogin #[inline(always)] 15240fe15e0SLoGin pub fn try_lock_irqsave(&self, flags: &mut usize) -> bool { 15340fe15e0SLoGin *flags = local_irq_save(); 154bacd691cSlogin if self.try_lock() { 155bacd691cSlogin return true; 156bacd691cSlogin } 15740fe15e0SLoGin local_irq_restore(*flags); 158bacd691cSlogin return false; 159bacd691cSlogin } 160d8a06412SGou Ngai } 161ec53d23eSlogin /// 实现了守卫的SpinLock, 能够支持内部可变性 162ec53d23eSlogin /// 163ec53d23eSlogin #[derive(Debug)] 164ec53d23eSlogin pub struct SpinLock<T> { 165ec53d23eSlogin lock: RawSpinlock, 166ec53d23eSlogin /// 自旋锁保护的数据 167ec53d23eSlogin data: UnsafeCell<T>, 168ec53d23eSlogin } 169ec53d23eSlogin 170ec53d23eSlogin /// SpinLock的守卫 171ec53d23eSlogin /// 该守卫没有构造器,并且其信息均为私有的。我们只能通过SpinLock的lock()方法获得一个守卫。 172ec53d23eSlogin /// 因此我们可以认为,只要能够获得一个守卫,那么数据就在自旋锁的保护之下。 173ec53d23eSlogin #[derive(Debug)] 174ec53d23eSlogin pub struct SpinLockGuard<'a, T: 'a> { 175ec53d23eSlogin lock: &'a SpinLock<T>, 17640fe15e0SLoGin flag: usize, 177ec53d23eSlogin } 178ec53d23eSlogin 179*90a0a490SLoGin impl<'a, T: 'a> SpinLockGuard<'a, T> { 180*90a0a490SLoGin /// 泄露自旋锁的守卫,返回一个可变的引用 181*90a0a490SLoGin /// 182*90a0a490SLoGin /// ## Safety 183*90a0a490SLoGin /// 184*90a0a490SLoGin /// 由于这样做可能导致守卫在另一个线程中被释放,从而导致pcb的preempt count不正确, 185*90a0a490SLoGin /// 因此必须小心的手动维护好preempt count。 186*90a0a490SLoGin /// 187*90a0a490SLoGin /// 并且,leak还可能导致锁的状态不正确。因此请仔细考虑是否真的需要使用这个函数。 188*90a0a490SLoGin #[inline] 189*90a0a490SLoGin pub unsafe fn leak(this: Self) -> &'a mut T { 190*90a0a490SLoGin // Use ManuallyDrop to avoid stacked-borrow invalidation 191*90a0a490SLoGin let this = ManuallyDrop::new(this); 192*90a0a490SLoGin // We know statically that only we are referencing data 193*90a0a490SLoGin unsafe { &mut *this.lock.data.get() } 194*90a0a490SLoGin } 195*90a0a490SLoGin } 196*90a0a490SLoGin 197ec53d23eSlogin /// 向编译器保证,SpinLock在线程之间是安全的. 198ec53d23eSlogin /// 其中要求类型T实现了Send这个Trait 199ec53d23eSlogin unsafe impl<T> Sync for SpinLock<T> where T: Send {} 200ec53d23eSlogin 201ec53d23eSlogin impl<T> SpinLock<T> { 202ec53d23eSlogin pub const fn new(value: T) -> Self { 203ec53d23eSlogin return Self { 204ec53d23eSlogin lock: RawSpinlock::INIT, 205ec53d23eSlogin data: UnsafeCell::new(value), 206ec53d23eSlogin }; 207ec53d23eSlogin } 208ec53d23eSlogin 209ec53d23eSlogin #[inline(always)] 210ec53d23eSlogin pub fn lock(&self) -> SpinLockGuard<T> { 211ec53d23eSlogin self.lock.lock(); 212ec53d23eSlogin // 加锁成功,返回一个守卫 213bacd691cSlogin return SpinLockGuard { 214bacd691cSlogin lock: self, 215bacd691cSlogin flag: 0, 216bacd691cSlogin }; 217bacd691cSlogin } 218bacd691cSlogin 219bacd691cSlogin pub fn lock_irqsave(&self) -> SpinLockGuard<T> { 22040fe15e0SLoGin let mut flags: usize = 0; 22140fe15e0SLoGin 222bacd691cSlogin self.lock.lock_irqsave(&mut flags); 223bacd691cSlogin // 加锁成功,返回一个守卫 224bacd691cSlogin return SpinLockGuard { 225bacd691cSlogin lock: self, 226bacd691cSlogin flag: flags, 227bacd691cSlogin }; 228bacd691cSlogin } 229bacd691cSlogin 230bacd691cSlogin pub fn try_lock(&self) -> Result<SpinLockGuard<T>, SystemError> { 231bacd691cSlogin if self.lock.try_lock() { 232bacd691cSlogin return Ok(SpinLockGuard { 233bacd691cSlogin lock: self, 234bacd691cSlogin flag: 0, 235bacd691cSlogin }); 236bacd691cSlogin } 23779a452ceShoumkh return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 238bacd691cSlogin } 239bacd691cSlogin 240bacd691cSlogin pub fn try_lock_irqsave(&self) -> Result<SpinLockGuard<T>, SystemError> { 24140fe15e0SLoGin let mut flags: usize = 0; 242bacd691cSlogin if self.lock.try_lock_irqsave(&mut flags) { 243bacd691cSlogin return Ok(SpinLockGuard { 244bacd691cSlogin lock: self, 245bacd691cSlogin flag: flags, 246bacd691cSlogin }); 247bacd691cSlogin } 24879a452ceShoumkh return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 249ec53d23eSlogin } 250*90a0a490SLoGin 251*90a0a490SLoGin /// 强制解锁,并且不更改preempt count 252*90a0a490SLoGin /// 253*90a0a490SLoGin /// ## Safety 254*90a0a490SLoGin /// 255*90a0a490SLoGin /// 由于这样做可能导致preempt count不正确,因此必须小心的手动维护好preempt count。 256*90a0a490SLoGin /// 如非必要,请不要使用这个函数。 257*90a0a490SLoGin pub unsafe fn force_unlock(&self) { 258*90a0a490SLoGin self.lock.unlock_no_preempt(); 259*90a0a490SLoGin } 260ec53d23eSlogin } 261ec53d23eSlogin 262ec53d23eSlogin /// 实现Deref trait,支持通过获取SpinLockGuard来获取临界区数据的不可变引用 263ec53d23eSlogin impl<T> Deref for SpinLockGuard<'_, T> { 264ec53d23eSlogin type Target = T; 265ec53d23eSlogin 266ec53d23eSlogin fn deref(&self) -> &Self::Target { 267ec53d23eSlogin return unsafe { &*self.lock.data.get() }; 268ec53d23eSlogin } 269ec53d23eSlogin } 270ec53d23eSlogin 271ec53d23eSlogin /// 实现DerefMut trait,支持通过获取SpinLockGuard来获取临界区数据的可变引用 272ec53d23eSlogin impl<T> DerefMut for SpinLockGuard<'_, T> { 273ec53d23eSlogin fn deref_mut(&mut self) -> &mut Self::Target { 274ec53d23eSlogin return unsafe { &mut *self.lock.data.get() }; 275ec53d23eSlogin } 276ec53d23eSlogin } 277ec53d23eSlogin 278ec53d23eSlogin /// @brief 为SpinLockGuard实现Drop方法,那么,一旦守卫的生命周期结束,就会自动释放自旋锁,避免了忘记放锁的情况 279ec53d23eSlogin impl<T> Drop for SpinLockGuard<'_, T> { 280ec53d23eSlogin fn drop(&mut self) { 281cde5492fSlogin if self.flag != 0 { 28240fe15e0SLoGin self.lock.lock.unlock_irqrestore(self.flag); 283cde5492fSlogin } else { 284ec53d23eSlogin self.lock.lock.unlock(); 285ec53d23eSlogin } 286ac643d42Slogin } 287cde5492fSlogin } 288