1 #![allow(dead_code)] 2 use core::cell::UnsafeCell; 3 use core::ops::{Deref, DerefMut}; 4 use core::ptr::read_volatile; 5 6 use core::sync::atomic::{AtomicBool, Ordering}; 7 8 use crate::arch::asm::irqflags::{local_irq_restore, local_irq_save}; 9 use crate::arch::interrupt::{cli, sti}; 10 use crate::include::bindings::bindings::{spin_lock, spin_unlock, spinlock_t}; 11 use crate::process::preempt::{preempt_disable, preempt_enable}; 12 13 /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁 14 #[inline] 15 pub fn spin_lock_irqsave(lock: *mut spinlock_t, flags: &mut u64) { 16 local_irq_save(flags); 17 unsafe { 18 spin_lock(lock); 19 } 20 } 21 22 /// @brief 恢复rflags以及中断状态并解锁自旋锁 23 #[inline] 24 pub fn spin_unlock_irqrestore(lock: *mut spinlock_t, flags: &u64) { 25 unsafe { 26 spin_unlock(lock); 27 } 28 // kdebug!("123"); 29 local_irq_restore(flags); 30 } 31 32 /// 判断一个自旋锁是否已经被加锁 33 #[inline] 34 pub fn spin_is_locked(lock: &spinlock_t) -> bool { 35 let val = unsafe { read_volatile(&lock.lock as *const i8) }; 36 37 return if val == 0 { true } else { false }; 38 } 39 40 impl Default for spinlock_t { 41 fn default() -> Self { 42 Self { lock: 1 } 43 } 44 } 45 46 /// @brief 关闭中断并加锁 47 pub fn spin_lock_irq(lock: *mut spinlock_t) { 48 cli(); 49 unsafe { 50 spin_lock(lock); 51 } 52 } 53 54 /// @brief 解锁并开中断 55 pub fn spin_unlock_irq(lock: *mut spinlock_t) { 56 unsafe { 57 spin_unlock(lock); 58 } 59 sti(); 60 } 61 62 /// 原始的Spinlock(自旋锁) 63 /// 请注意,这个自旋锁和C的不兼容。 64 /// 65 /// @param self.0 这个AtomicBool的值为false时,表示没有被加锁。当它为true时,表示自旋锁已经被上锁。 66 #[derive(Debug)] 67 pub struct RawSpinlock(AtomicBool); 68 69 impl RawSpinlock { 70 /// @brief 初始化自旋锁 71 pub const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false)); 72 73 /// @brief 加锁 74 pub fn lock(&self) { 75 while !self.try_lock() {} 76 } 77 78 /// @brief 关中断并加锁 79 pub fn lock_irq(&self) { 80 cli(); 81 self.lock(); 82 } 83 84 /// @brief 尝试加锁 85 /// @return 加锁成功->true 86 /// 加锁失败->false 87 pub fn try_lock(&self) -> bool { 88 // 先增加自旋锁持有计数 89 preempt_disable(); 90 91 let res = self 92 .0 93 .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) 94 .is_ok(); 95 96 // 如果加锁失败恢复自旋锁持有计数 97 if res == false { 98 preempt_enable(); 99 } 100 return res; 101 } 102 103 /// @brief 解锁 104 pub fn unlock(&self) { 105 // 减少自旋锁持有计数 106 preempt_enable(); 107 self.0.store(false, Ordering::Release); 108 } 109 110 /// @brief 放锁并开中断 111 pub fn unlock_irq(&self) { 112 self.unlock(); 113 sti(); 114 } 115 116 /// @brief 判断自旋锁是否被上锁 117 /// 118 /// @return true 自旋锁被上锁 119 /// @return false 自旋锁处于解锁状态 120 pub fn is_locked(&self) -> bool { 121 return self.0.load(Ordering::Relaxed).into(); 122 } 123 124 /// @brief 强制设置自旋锁的状态 125 /// 请注意,这样操作可能会带来未知的风险。因此它是unsafe的。(尽管从Rust语言本身来说,它是safe的) 126 pub unsafe fn set_value(&mut self, value: bool) { 127 self.0.store(value, Ordering::SeqCst); 128 } 129 130 /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁 131 pub fn lock_irqsave(&self, flags: &mut u64) { 132 local_irq_save(flags); 133 self.lock(); 134 } 135 136 /// @brief 恢复rflags以及中断状态并解锁自旋锁 137 pub fn unlock_irqrestore(&self, flags: &u64) { 138 self.unlock(); 139 local_irq_restore(flags); 140 } 141 } 142 /// 实现了守卫的SpinLock, 能够支持内部可变性 143 /// 144 #[derive(Debug)] 145 pub struct SpinLock<T> { 146 lock: RawSpinlock, 147 /// 自旋锁保护的数据 148 data: UnsafeCell<T>, 149 } 150 151 /// SpinLock的守卫 152 /// 该守卫没有构造器,并且其信息均为私有的。我们只能通过SpinLock的lock()方法获得一个守卫。 153 /// 因此我们可以认为,只要能够获得一个守卫,那么数据就在自旋锁的保护之下。 154 #[derive(Debug)] 155 pub struct SpinLockGuard<'a, T: 'a> { 156 lock: &'a SpinLock<T>, 157 } 158 159 /// 向编译器保证,SpinLock在线程之间是安全的. 160 /// 其中要求类型T实现了Send这个Trait 161 unsafe impl<T> Sync for SpinLock<T> where T: Send {} 162 163 impl<T> SpinLock<T> { 164 pub const fn new(value: T) -> Self { 165 return Self { 166 lock: RawSpinlock::INIT, 167 data: UnsafeCell::new(value), 168 }; 169 } 170 171 #[inline(always)] 172 pub fn lock(&self) -> SpinLockGuard<T> { 173 self.lock.lock(); 174 // 加锁成功,返回一个守卫 175 return SpinLockGuard { lock: self }; 176 } 177 } 178 179 /// 实现Deref trait,支持通过获取SpinLockGuard来获取临界区数据的不可变引用 180 impl<T> Deref for SpinLockGuard<'_, T> { 181 type Target = T; 182 183 fn deref(&self) -> &Self::Target { 184 return unsafe { &*self.lock.data.get() }; 185 } 186 } 187 188 /// 实现DerefMut trait,支持通过获取SpinLockGuard来获取临界区数据的可变引用 189 impl<T> DerefMut for SpinLockGuard<'_, T> { 190 fn deref_mut(&mut self) -> &mut Self::Target { 191 return unsafe { &mut *self.lock.data.get() }; 192 } 193 } 194 195 /// @brief 为SpinLockGuard实现Drop方法,那么,一旦守卫的生命周期结束,就会自动释放自旋锁,避免了忘记放锁的情况 196 impl<T> Drop for SpinLockGuard<'_, T> { 197 fn drop(&mut self) { 198 self.lock.lock.unlock(); 199 } 200 } 201