166f67c6aSlogin #![allow(dead_code)] 266f67c6aSlogin use core::ptr::read_volatile; 366f67c6aSlogin 4ac643d42Slogin use core::sync::atomic::{AtomicBool, Ordering}; 5ac643d42Slogin 6adc1846bSlogin use crate::arch::asm::irqflags::{local_irq_restore, local_irq_save}; 7adc1846bSlogin use crate::arch::interrupt::{cli, sti}; 866f67c6aSlogin use crate::include::bindings::bindings::{spin_lock, spin_unlock, spinlock_t}; 9ac643d42Slogin use crate::process::preempt::{preempt_disable, preempt_enable}; 1066f67c6aSlogin 1166f67c6aSlogin /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁 121a2eaa40Slogin #[inline] 1366f67c6aSlogin pub fn spin_lock_irqsave(lock: *mut spinlock_t, flags: &mut u64) { 1466f67c6aSlogin local_irq_save(flags); 1566f67c6aSlogin unsafe { 1666f67c6aSlogin spin_lock(lock); 1766f67c6aSlogin } 1866f67c6aSlogin } 1966f67c6aSlogin 2066f67c6aSlogin /// @brief 恢复rflags以及中断状态并解锁自旋锁 211a2eaa40Slogin #[inline] 2266f67c6aSlogin pub fn spin_unlock_irqrestore(lock: *mut spinlock_t, flags: &u64) { 2366f67c6aSlogin unsafe { 2466f67c6aSlogin spin_unlock(lock); 2566f67c6aSlogin } 2666f67c6aSlogin // kdebug!("123"); 2766f67c6aSlogin local_irq_restore(flags); 2866f67c6aSlogin } 2966f67c6aSlogin 3066f67c6aSlogin /// 判断一个自旋锁是否已经被加锁 311a2eaa40Slogin #[inline] 3266f67c6aSlogin pub fn spin_is_locked(lock: &spinlock_t) -> bool { 3366f67c6aSlogin let val = unsafe { read_volatile(&lock.lock as *const i8) }; 3466f67c6aSlogin 3566f67c6aSlogin return if val == 0 { true } else { false }; 3666f67c6aSlogin } 37c8025a88Slogin 38c8025a88Slogin impl Default for spinlock_t { 39c8025a88Slogin fn default() -> Self { 40c8025a88Slogin Self { lock: 1 } 41c8025a88Slogin } 42c8025a88Slogin } 431a2eaa40Slogin 441a2eaa40Slogin /// @brief 关闭中断并加锁 451a2eaa40Slogin pub fn spin_lock_irq(lock: *mut spinlock_t) { 461a2eaa40Slogin cli(); 47ac643d42Slogin unsafe { 48ac643d42Slogin spin_lock(lock); 49ac643d42Slogin } 501a2eaa40Slogin } 511a2eaa40Slogin 521a2eaa40Slogin /// @brief 解锁并开中断 531a2eaa40Slogin pub fn spin_unlock_irq(lock: *mut spinlock_t) { 54ac643d42Slogin unsafe { 55ac643d42Slogin spin_unlock(lock); 56ac643d42Slogin } 571a2eaa40Slogin sti(); 581a2eaa40Slogin } 59ac643d42Slogin 60*d4f3de93Slogin #[derive(Debug)] 61ac643d42Slogin pub struct RawSpinlock(AtomicBool); 62ac643d42Slogin 63ac643d42Slogin impl RawSpinlock { 64ac643d42Slogin /// @brief 初始化自旋锁 65*d4f3de93Slogin pub const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false)); 66ac643d42Slogin 67ac643d42Slogin /// @brief 加锁 68ac643d42Slogin pub fn lock(&mut self) { 69ac643d42Slogin while !self.try_lock() {} 70ac643d42Slogin } 71ac643d42Slogin 72ac643d42Slogin /// @brief 关中断并加锁 73ac643d42Slogin pub fn lock_irq(&mut self){ 74ac643d42Slogin cli(); 75ac643d42Slogin self.lock(); 76ac643d42Slogin } 77ac643d42Slogin 78ac643d42Slogin /// @brief 尝试加锁 79ac643d42Slogin /// @return 加锁成功->true 80ac643d42Slogin /// 加锁失败->false 81ac643d42Slogin pub fn try_lock(&mut self) -> bool { 82ac643d42Slogin // 先增加自旋锁持有计数 83ac643d42Slogin preempt_disable(); 84ac643d42Slogin 85ac643d42Slogin let res = self 86ac643d42Slogin .0 87ac643d42Slogin .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) 88ac643d42Slogin .is_ok(); 89ac643d42Slogin 90ac643d42Slogin // 如果加锁失败恢复自旋锁持有计数 91ac643d42Slogin if res == false { 92ac643d42Slogin preempt_enable(); 93ac643d42Slogin } 94ac643d42Slogin return res; 95ac643d42Slogin } 96ac643d42Slogin 97ac643d42Slogin /// @brief 解锁 98ac643d42Slogin pub fn unlock(&mut self){ 99ac643d42Slogin // 减少自旋锁持有计数 100ac643d42Slogin preempt_enable(); 101ac643d42Slogin self.0.store(false, Ordering::Release); 102ac643d42Slogin } 103ac643d42Slogin 104ac643d42Slogin /// @brief 放锁并开中断 105ac643d42Slogin pub fn unlock_irq(&mut self){ 106ac643d42Slogin self.unlock(); 107ac643d42Slogin sti(); 108ac643d42Slogin } 109ac643d42Slogin 110ac643d42Slogin // todo: spin_lock_irqsave 111ac643d42Slogin // todo: spin_unlock_irqrestore 112ac643d42Slogin 113ac643d42Slogin } 114