new:新增rust写的RawSpinlock (#127)

This commit is contained in:
login 2022-12-25 23:53:35 +08:00 committed by GitHub
parent 9983902105
commit ac643d420b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,9 +1,12 @@
#![allow(dead_code)] #![allow(dead_code)]
use core::ptr::read_volatile; 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::asm::irqflags::{local_irq_restore, local_irq_save};
use crate::arch::x86_64::interrupt::{cli, sti}; use crate::arch::x86_64::interrupt::{cli, sti};
use crate::include::bindings::bindings::{spin_lock, spin_unlock, spinlock_t}; use crate::include::bindings::bindings::{spin_lock, spin_unlock, spinlock_t};
use crate::process::preempt::{preempt_disable, preempt_enable};
/// @brief 保存中断状态到flags中关闭中断并对自旋锁加锁 /// @brief 保存中断状态到flags中关闭中断并对自旋锁加锁
#[inline] #[inline]
@ -39,13 +42,71 @@ impl Default for spinlock_t {
} }
/// @brief 关闭中断并加锁 /// @brief 关闭中断并加锁
pub fn spin_lock_irq(lock: *mut spinlock_t){ pub fn spin_lock_irq(lock: *mut spinlock_t) {
cli(); cli();
unsafe{spin_lock(lock);} unsafe {
spin_lock(lock);
}
} }
/// @brief 解锁并开中断 /// @brief 解锁并开中断
pub fn spin_unlock_irq(lock: *mut spinlock_t){ pub fn spin_unlock_irq(lock: *mut spinlock_t) {
unsafe{spin_unlock(lock);} unsafe {
spin_unlock(lock);
}
sti(); 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
}