166f67c6aSlogin #![allow(dead_code)] 2ec53d23eSlogin use core::cell::UnsafeCell; 3ec53d23eSlogin use core::ops::{Deref, DerefMut}; 466f67c6aSlogin use core::ptr::read_volatile; 566f67c6aSlogin 6ac643d42Slogin use core::sync::atomic::{AtomicBool, Ordering}; 7ac643d42Slogin 8adc1846bSlogin use crate::arch::asm::irqflags::{local_irq_restore, local_irq_save}; 9adc1846bSlogin use crate::arch::interrupt::{cli, sti}; 1066f67c6aSlogin use crate::include::bindings::bindings::{spin_lock, spin_unlock, spinlock_t}; 11ac643d42Slogin use crate::process::preempt::{preempt_disable, preempt_enable}; 12bacd691cSlogin use crate::syscall::SystemError; 1366f67c6aSlogin 1466f67c6aSlogin /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁 151a2eaa40Slogin #[inline] 1666f67c6aSlogin pub fn spin_lock_irqsave(lock: *mut spinlock_t, flags: &mut u64) { 1766f67c6aSlogin local_irq_save(flags); 1866f67c6aSlogin unsafe { 1966f67c6aSlogin spin_lock(lock); 2066f67c6aSlogin } 2166f67c6aSlogin } 2266f67c6aSlogin 2366f67c6aSlogin /// @brief 恢复rflags以及中断状态并解锁自旋锁 241a2eaa40Slogin #[inline] 2566f67c6aSlogin pub fn spin_unlock_irqrestore(lock: *mut spinlock_t, flags: &u64) { 2666f67c6aSlogin unsafe { 2766f67c6aSlogin spin_unlock(lock); 2866f67c6aSlogin } 2966f67c6aSlogin // kdebug!("123"); 3066f67c6aSlogin 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 111ac643d42Slogin /// @brief 放锁并开中断 112ec53d23eSlogin pub fn unlock_irq(&self) { 113ac643d42Slogin self.unlock(); 114ac643d42Slogin sti(); 115ac643d42Slogin } 116ac643d42Slogin 11761de2cdcSlogin /// @brief 判断自旋锁是否被上锁 11861de2cdcSlogin /// 11961de2cdcSlogin /// @return true 自旋锁被上锁 12061de2cdcSlogin /// @return false 自旋锁处于解锁状态 121ec53d23eSlogin pub fn is_locked(&self) -> bool { 12261de2cdcSlogin return self.0.load(Ordering::Relaxed).into(); 12361de2cdcSlogin } 12461de2cdcSlogin 12561de2cdcSlogin /// @brief 强制设置自旋锁的状态 12661de2cdcSlogin /// 请注意,这样操作可能会带来未知的风险。因此它是unsafe的。(尽管从Rust语言本身来说,它是safe的) 12761de2cdcSlogin pub unsafe fn set_value(&mut self, value: bool) { 12861de2cdcSlogin self.0.store(value, Ordering::SeqCst); 12961de2cdcSlogin } 13061de2cdcSlogin 131d8a06412SGou Ngai /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁 132d8a06412SGou Ngai pub fn lock_irqsave(&self, flags: &mut u64) { 133d8a06412SGou Ngai local_irq_save(flags); 134d8a06412SGou Ngai self.lock(); 135ec53d23eSlogin } 136ac643d42Slogin 137d8a06412SGou Ngai /// @brief 恢复rflags以及中断状态并解锁自旋锁 138d8a06412SGou Ngai pub fn unlock_irqrestore(&self, flags: &u64) { 139d8a06412SGou Ngai self.unlock(); 140d8a06412SGou Ngai local_irq_restore(flags); 141d8a06412SGou Ngai } 142bacd691cSlogin 143bacd691cSlogin /// @brief 尝试保存中断状态到flags中,关闭中断,并对自旋锁加锁 144bacd691cSlogin /// @return 加锁成功->true 145bacd691cSlogin /// 加锁失败->false 146bacd691cSlogin #[inline(always)] 147bacd691cSlogin pub fn try_lock_irqsave(&self, flags: &mut u64) -> bool { 148bacd691cSlogin local_irq_save(flags); 149bacd691cSlogin if self.try_lock() { 150bacd691cSlogin return true; 151bacd691cSlogin } 152bacd691cSlogin local_irq_restore(flags); 153bacd691cSlogin return false; 154bacd691cSlogin } 155d8a06412SGou Ngai } 156ec53d23eSlogin /// 实现了守卫的SpinLock, 能够支持内部可变性 157ec53d23eSlogin /// 158ec53d23eSlogin #[derive(Debug)] 159ec53d23eSlogin pub struct SpinLock<T> { 160ec53d23eSlogin lock: RawSpinlock, 161ec53d23eSlogin /// 自旋锁保护的数据 162ec53d23eSlogin data: UnsafeCell<T>, 163ec53d23eSlogin } 164ec53d23eSlogin 165ec53d23eSlogin /// SpinLock的守卫 166ec53d23eSlogin /// 该守卫没有构造器,并且其信息均为私有的。我们只能通过SpinLock的lock()方法获得一个守卫。 167ec53d23eSlogin /// 因此我们可以认为,只要能够获得一个守卫,那么数据就在自旋锁的保护之下。 168ec53d23eSlogin #[derive(Debug)] 169ec53d23eSlogin pub struct SpinLockGuard<'a, T: 'a> { 170ec53d23eSlogin lock: &'a SpinLock<T>, 171bacd691cSlogin flag: u64, 172ec53d23eSlogin } 173ec53d23eSlogin 174ec53d23eSlogin /// 向编译器保证,SpinLock在线程之间是安全的. 175ec53d23eSlogin /// 其中要求类型T实现了Send这个Trait 176ec53d23eSlogin unsafe impl<T> Sync for SpinLock<T> where T: Send {} 177ec53d23eSlogin 178ec53d23eSlogin impl<T> SpinLock<T> { 179ec53d23eSlogin pub const fn new(value: T) -> Self { 180ec53d23eSlogin return Self { 181ec53d23eSlogin lock: RawSpinlock::INIT, 182ec53d23eSlogin data: UnsafeCell::new(value), 183ec53d23eSlogin }; 184ec53d23eSlogin } 185ec53d23eSlogin 186ec53d23eSlogin #[inline(always)] 187ec53d23eSlogin pub fn lock(&self) -> SpinLockGuard<T> { 188ec53d23eSlogin self.lock.lock(); 189ec53d23eSlogin // 加锁成功,返回一个守卫 190bacd691cSlogin return SpinLockGuard { 191bacd691cSlogin lock: self, 192bacd691cSlogin flag: 0, 193bacd691cSlogin }; 194bacd691cSlogin } 195bacd691cSlogin 196bacd691cSlogin pub fn lock_irqsave(&self) -> SpinLockGuard<T> { 197bacd691cSlogin let mut flags: u64 = 0; 198bacd691cSlogin self.lock.lock_irqsave(&mut flags); 199bacd691cSlogin // 加锁成功,返回一个守卫 200bacd691cSlogin return SpinLockGuard { 201bacd691cSlogin lock: self, 202bacd691cSlogin flag: flags, 203bacd691cSlogin }; 204bacd691cSlogin } 205bacd691cSlogin 206bacd691cSlogin pub fn try_lock(&self) -> Result<SpinLockGuard<T>, SystemError> { 207bacd691cSlogin if self.lock.try_lock() { 208bacd691cSlogin return Ok(SpinLockGuard { 209bacd691cSlogin lock: self, 210bacd691cSlogin flag: 0, 211bacd691cSlogin }); 212bacd691cSlogin } 213*79a452ceShoumkh return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 214bacd691cSlogin } 215bacd691cSlogin 216bacd691cSlogin pub fn try_lock_irqsave(&self) -> Result<SpinLockGuard<T>, SystemError> { 217bacd691cSlogin let mut flags: u64 = 0; 218bacd691cSlogin if self.lock.try_lock_irqsave(&mut flags) { 219bacd691cSlogin return Ok(SpinLockGuard { 220bacd691cSlogin lock: self, 221bacd691cSlogin flag: flags, 222bacd691cSlogin }); 223bacd691cSlogin } 224*79a452ceShoumkh return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 225ec53d23eSlogin } 226ec53d23eSlogin } 227ec53d23eSlogin 228ec53d23eSlogin /// 实现Deref trait,支持通过获取SpinLockGuard来获取临界区数据的不可变引用 229ec53d23eSlogin impl<T> Deref for SpinLockGuard<'_, T> { 230ec53d23eSlogin type Target = T; 231ec53d23eSlogin 232ec53d23eSlogin fn deref(&self) -> &Self::Target { 233ec53d23eSlogin return unsafe { &*self.lock.data.get() }; 234ec53d23eSlogin } 235ec53d23eSlogin } 236ec53d23eSlogin 237ec53d23eSlogin /// 实现DerefMut trait,支持通过获取SpinLockGuard来获取临界区数据的可变引用 238ec53d23eSlogin impl<T> DerefMut for SpinLockGuard<'_, T> { 239ec53d23eSlogin fn deref_mut(&mut self) -> &mut Self::Target { 240ec53d23eSlogin return unsafe { &mut *self.lock.data.get() }; 241ec53d23eSlogin } 242ec53d23eSlogin } 243ec53d23eSlogin 244ec53d23eSlogin /// @brief 为SpinLockGuard实现Drop方法,那么,一旦守卫的生命周期结束,就会自动释放自旋锁,避免了忘记放锁的情况 245ec53d23eSlogin impl<T> Drop for SpinLockGuard<'_, T> { 246ec53d23eSlogin fn drop(&mut self) { 247ec53d23eSlogin self.lock.lock.unlock(); 248ec53d23eSlogin } 249ac643d42Slogin } 250