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 pub struct RawSpinlock(AtomicBool); 61 62 impl RawSpinlock { 63 /// @brief 初始化自旋锁 64 const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false)); 65 66 /// @brief 加锁 67 pub fn lock(&mut self) { 68 while !self.try_lock() {} 69 } 70 71 /// @brief 关中断并加锁 72 pub fn lock_irq(&mut self){ 73 cli(); 74 self.lock(); 75 } 76 77 /// @brief 尝试加锁 78 /// @return 加锁成功->true 79 /// 加锁失败->false 80 pub fn try_lock(&mut self) -> bool { 81 // 先增加自旋锁持有计数 82 preempt_disable(); 83 84 let res = self 85 .0 86 .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) 87 .is_ok(); 88 89 // 如果加锁失败恢复自旋锁持有计数 90 if res == false { 91 preempt_enable(); 92 } 93 return res; 94 } 95 96 /// @brief 解锁 97 pub fn unlock(&mut self){ 98 // 减少自旋锁持有计数 99 preempt_enable(); 100 self.0.store(false, Ordering::Release); 101 } 102 103 /// @brief 放锁并开中断 104 pub fn unlock_irq(&mut self){ 105 self.unlock(); 106 sti(); 107 } 108 109 // todo: spin_lock_irqsave 110 // todo: spin_unlock_irqrestore 111 112 } 113