|
@@ -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();
|
|
|
-}
|
|
|
+}
|
|
|
+
|
|
|
+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
|
|
|
+
|
|
|
+}
|