diff --git a/kernel/src/libs/spinlock.rs b/kernel/src/libs/spinlock.rs index 39ab23da..423c1feb 100644 --- a/kernel/src/libs/spinlock.rs +++ b/kernel/src/libs/spinlock.rs @@ -1,9 +1,12 @@ #![allow(dead_code)] use core::ptr::read_volatile; +use core::sync::atomic::{AtomicBool, Ordering}; + use crate::arch::x86_64::asm::irqflags::{local_irq_restore, local_irq_save}; use crate::arch::x86_64::interrupt::{cli, sti}; use crate::include::bindings::bindings::{spin_lock, spin_unlock, spinlock_t}; +use crate::process::preempt::{preempt_disable, preempt_enable}; /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁 #[inline] @@ -39,13 +42,71 @@ impl Default for spinlock_t { } /// @brief 关闭中断并加锁 -pub fn spin_lock_irq(lock: *mut spinlock_t){ +pub fn spin_lock_irq(lock: *mut spinlock_t) { cli(); - unsafe{spin_lock(lock);} + unsafe { + spin_lock(lock); + } } /// @brief 解锁并开中断 -pub fn spin_unlock_irq(lock: *mut spinlock_t){ - unsafe{spin_unlock(lock);} +pub fn spin_unlock_irq(lock: *mut spinlock_t) { + unsafe { + spin_unlock(lock); + } sti(); -} \ No newline at end of file +} + +pub struct RawSpinlock(AtomicBool); + +impl RawSpinlock { + /// @brief 初始化自旋锁 + const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false)); + + /// @brief 加锁 + pub fn lock(&mut self) { + while !self.try_lock() {} + } + + /// @brief 关中断并加锁 + pub fn lock_irq(&mut self){ + cli(); + self.lock(); + } + + /// @brief 尝试加锁 + /// @return 加锁成功->true + /// 加锁失败->false + pub fn try_lock(&mut self) -> bool { + // 先增加自旋锁持有计数 + preempt_disable(); + + let res = self + .0 + .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) + .is_ok(); + + // 如果加锁失败恢复自旋锁持有计数 + if res == false { + preempt_enable(); + } + return res; + } + + /// @brief 解锁 + pub fn unlock(&mut self){ + // 减少自旋锁持有计数 + preempt_enable(); + self.0.store(false, Ordering::Release); + } + + /// @brief 放锁并开中断 + pub fn unlock_irq(&mut self){ + self.unlock(); + sti(); + } + + // todo: spin_lock_irqsave + // todo: spin_unlock_irqrestore + +}