Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions kernel/src/libs/wait_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,17 @@ impl WaitQueue {
guard.wait_list.push_back(ProcessManager::current_pcb());
drop(guard);
}

pub unsafe fn sleep_without_schedule_uninterruptible(&self) {
// 安全检查:确保当前处于中断禁止状态
assert!(CurrentIrqArch::is_irq_enabled() == false);
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
ProcessManager::sleep(false).unwrap_or_else(|e| {
panic!("sleep error: {:?}", e);
});
guard.wait_list.push_back(ProcessManager::current_pcb());
drop(guard);
}
/// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断
pub fn sleep_uninterruptible(&self) {
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
Expand Down
152 changes: 152 additions & 0 deletions kernel/src/sched/completion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
use crate::{
libs::{spinlock::SpinLock, wait_queue::WaitQueue},
syscall::SystemError,
time::timer::schedule_timeout,
};

const COMPLETE_ALL: u32 = core::u32::MAX;
const MAX_TIMEOUT: i64 = core::i64::MAX;

#[derive(Debug)]
pub struct Completion {
inner: SpinLock<InnerCompletion>,
}

impl Completion {
pub const fn new() -> Self {
Self {
inner: SpinLock::new(InnerCompletion::new()),
}
}

/// @brief 基本函数:通用的处理wait命令的函数(即所有wait_for_completion函数最核心部分在这里)
///
/// @param timeout 非负整数
/// @param interuptible 设置进程是否能被打断
/// @return 返回剩余时间或者SystemError
fn do_wait_for_common(&self, mut timeout: i64, interuptible: bool) -> Result<i64, SystemError> {
let mut inner = self.inner.lock_irqsave();

if inner.done == 0 {
//loop break 类似 do while 保证进行一次信号检测
loop {
//检查当前线程是否有未处理的信号
// if (signal_pending_state(state, current)) {
// timeout = -ERESTARTSYS;
// break;
//}

if interuptible {
unsafe { inner.wait_queue.sleep_without_schedule() };
} else {
unsafe { inner.wait_queue.sleep_without_schedule_uninterruptible() };
}
drop(inner);
timeout = schedule_timeout(timeout)?;
inner = self.inner.lock_irqsave();
if inner.done != 0 || timeout <= 0 {
break;
}
}
inner.wait_queue.wakeup(None);
if inner.done == 0 {
drop(inner);
return Ok(timeout);
}
}
if inner.done != COMPLETE_ALL {
inner.done -= 1;
}
drop(inner);
return Ok(if timeout > 0 { timeout } else { 1 });
}

/// @brief 等待指定时间,超时后就返回, 同时设置pcb state为uninteruptible.
/// @param timeout 非负整数,等待指定时间,超时后就返回/或者提前done
pub fn wait_for_completion_timeout(&self, timeout: i64) -> Result<i64, SystemError> {
self.do_wait_for_common(timeout, false)
}

/// @brief 等待completion命令唤醒进程, 同时设置pcb state 为uninteruptible.
pub fn wait_for_completion(&self) -> Result<i64, SystemError> {
self.do_wait_for_common(MAX_TIMEOUT, false)
}

/// @brief @brief 等待completion的完成,但是可以被中断
pub fn wait_for_completion_interruptible(&self) -> Result<i64, SystemError> {
self.do_wait_for_common(MAX_TIMEOUT, true)
}

pub fn wait_for_completion_interruptible_timeout(
&mut self,
timeout: i64,
) -> Result<i64, SystemError> {
assert!(timeout >= 0);
self.do_wait_for_common(timeout, true)
}

/// @brief 唤醒一个wait_queue中的节点
pub fn complete(&self) {
let mut inner = self.inner.lock_irqsave();
if inner.done != COMPLETE_ALL {
inner.done += 1;
}
inner.wait_queue.wakeup(None);
// 脱离生命周期,自动释放guard
}

/// @brief 永久标记done为Complete_All,并从wait_queue中删除所有节点
pub fn complete_all(&mut self) {
let mut inner = self.inner.lock_irqsave();
inner.done = COMPLETE_ALL;
inner.wait_queue.wakeup_all(None);
// 脱离生命周期,自动释放guard
}

/// @brief @brief 尝试获取completion的一个done!如果您在wait之前加上这个函数作为判断,说不定会加快运行速度。
///
/// @return true - 表示不需要wait_for_completion,并且已经获取到了一个completion(即返回true意味着done已经被 减1 )
/// @return false - 表示当前done=0,您需要进入等待,即wait_for_completion
pub fn try_wait_for_completion(&mut self) -> bool {
let mut inner = self.inner.lock_irqsave();
if inner.done == 0 {
return false;
}

if inner.done != 0 {
return false;
} else if inner.done != COMPLETE_ALL {
inner.done -= 1;
}
return true;
// 脱离生命周期,自动释放guard
}

// @brief 测试一个completion是否有waiter。(即done是不是等于0)
pub fn completion_done(&self) -> bool {
let inner = self.inner.lock_irqsave();
if inner.done == 0 {
return false;
}

if inner.done == 0 {
return false;
}
return true;
// 脱离生命周期,自动释放guard
}
}
#[derive(Debug)]
pub struct InnerCompletion {
done: u32,
wait_queue: WaitQueue,
}

impl InnerCompletion {
pub const fn new() -> Self {
Self {
done: 0,
wait_queue: WaitQueue::INIT,
}
}
}
1 change: 1 addition & 0 deletions kernel/src/sched/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod cfs;
pub mod completion;
pub mod core;
pub mod rt;
pub mod syscall;
Expand Down