1 #![allow(dead_code)] 2 use core::ptr::read_volatile; 3 4 use core::sync::atomic::{AtomicBool, Ordering}; 5 6 use crate::arch::asm::irqflags::{local_irq_restore, local_irq_save}; 7 use crate::arch::interrupt::{cli, sti}; 8 use crate::include::bindings::bindings::{spin_lock, spin_unlock, spinlock_t}; 9 use crate::process::preempt::{preempt_disable, preempt_enable}; 10 11 /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁 12 #[inline] 13 pub fn spin_lock_irqsave(lock: *mut spinlock_t, flags: &mut u64) { 14 local_irq_save(flags); 15 unsafe { 16 spin_lock(lock); 17 } 18 } 19 20 /// @brief 恢复rflags以及中断状态并解锁自旋锁 21 #[inline] 22 pub fn spin_unlock_irqrestore(lock: *mut spinlock_t, flags: &u64) { 23 unsafe { 24 spin_unlock(lock); 25 } 26 // kdebug!("123"); 27 local_irq_restore(flags); 28 } 29 30 /// 判断一个自旋锁是否已经被加锁 31 #[inline] 32 pub fn spin_is_locked(lock: &spinlock_t) -> bool { 33 let val = unsafe { read_volatile(&lock.lock as *const i8) }; 34 35 return if val == 0 { true } else { false }; 36 } 37 38 impl Default for spinlock_t { 39 fn default() -> Self { 40 Self { lock: 1 } 41 } 42 } 43 44 /// @brief 关闭中断并加锁 45 pub fn spin_lock_irq(lock: *mut spinlock_t) { 46 cli(); 47 unsafe { 48 spin_lock(lock); 49 } 50 } 51 52 /// @brief 解锁并开中断 53 pub fn spin_unlock_irq(lock: *mut spinlock_t) { 54 unsafe { 55 spin_unlock(lock); 56 } 57 sti(); 58 } 59 60 /// 原始的Spinlock(自旋锁) 61 /// 请注意,这个自旋锁和C的不兼容。 62 /// 63 /// @param self.0 这个AtomicBool的值为false时,表示没有被加锁。当它为true时,表示自旋锁已经被上锁。 64 #[derive(Debug)] 65 pub struct RawSpinlock(AtomicBool); 66 67 impl RawSpinlock { 68 /// @brief 初始化自旋锁 69 pub const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false)); 70 71 /// @brief 加锁 72 pub fn lock(&mut self) { 73 while !self.try_lock() {} 74 } 75 76 /// @brief 关中断并加锁 77 pub fn lock_irq(&mut self){ 78 cli(); 79 self.lock(); 80 } 81 82 /// @brief 尝试加锁 83 /// @return 加锁成功->true 84 /// 加锁失败->false 85 pub fn try_lock(&mut self) -> bool { 86 // 先增加自旋锁持有计数 87 preempt_disable(); 88 89 let res = self 90 .0 91 .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) 92 .is_ok(); 93 94 // 如果加锁失败恢复自旋锁持有计数 95 if res == false { 96 preempt_enable(); 97 } 98 return res; 99 } 100 101 /// @brief 解锁 102 pub fn unlock(&mut self){ 103 // 减少自旋锁持有计数 104 preempt_enable(); 105 self.0.store(false, Ordering::Release); 106 } 107 108 /// @brief 放锁并开中断 109 pub fn unlock_irq(&mut self){ 110 self.unlock(); 111 sti(); 112 } 113 114 /// @brief 判断自旋锁是否被上锁 115 /// 116 /// @return true 自旋锁被上锁 117 /// @return false 自旋锁处于解锁状态 118 pub fn is_locked(&self)->bool 119 { 120 return self.0.load(Ordering::Relaxed).into(); 121 } 122 123 /// @brief 强制设置自旋锁的状态 124 /// 请注意,这样操作可能会带来未知的风险。因此它是unsafe的。(尽管从Rust语言本身来说,它是safe的) 125 pub unsafe fn set_value(&mut self, value:bool){ 126 self.0.store(value, Ordering::SeqCst); 127 } 128 129 // todo: spin_lock_irqsave 130 // todo: spin_unlock_irqrestore 131 132 } 133