Skip to content

Commit

Permalink
调整rust版本的waitqueue中的pcb为新版的pcb (#343)
Browse files Browse the repository at this point in the history
  • Loading branch information
Chiichen committed Aug 24, 2023
1 parent 781a1ed commit 9586833
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 57 deletions.
18 changes: 13 additions & 5 deletions kernel/src/ipc/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use crate::{
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
PollStatus,
},
include::bindings::bindings::PROC_INTERRUPTIBLE,
libs::{spinlock::SpinLock, wait_queue::WaitQueue},
process::ProcessState,
syscall::SystemError,
time::TimeSpec,
};
Expand Down Expand Up @@ -87,7 +87,9 @@ impl IndexNode for LockedPipeInode {

//如果管道里面没有数据,则唤醒写端,
while inode.valid_cnt == 0 {
inode.write_wait_queue.wakeup(PROC_INTERRUPTIBLE.into());
inode
.write_wait_queue
.wakeup(Some(ProcessState::Blocked(true)));

// 在读等待队列中睡眠,并释放锁
unsafe {
Expand Down Expand Up @@ -126,7 +128,9 @@ impl IndexNode for LockedPipeInode {
inode.valid_cnt -= num as i32;

//读完后解锁并唤醒等待在写等待队列中的进程
inode.write_wait_queue.wakeup(PROC_INTERRUPTIBLE.into());
inode
.write_wait_queue
.wakeup(Some(ProcessState::Blocked(true)));
//返回读取的字节数
return Ok(num);
}
Expand Down Expand Up @@ -169,7 +173,9 @@ impl IndexNode for LockedPipeInode {

while len + inode.valid_cnt as usize > PIPE_BUFF_SIZE {
// 唤醒读端
inode.read_wait_queue.wakeup(PROC_INTERRUPTIBLE.into());
inode
.read_wait_queue
.wakeup(Some(ProcessState::Blocked(true)));
// 解锁并睡眠
unsafe {
let irq_guard = CurrentIrqArch::save_and_disable_irq();
Expand Down Expand Up @@ -197,7 +203,9 @@ impl IndexNode for LockedPipeInode {
inode.valid_cnt += len as i32;

// 读完后解锁并唤醒等待在读等待队列中的进程
inode.read_wait_queue.wakeup(PROC_INTERRUPTIBLE.into());
inode
.read_wait_queue
.wakeup(Some(ProcessState::Blocked(true)));
// 返回写入的字节数
return Ok(len);
}
Expand Down
6 changes: 3 additions & 3 deletions kernel/src/libs/semaphore.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::sync::atomic::{AtomicI32, Ordering};

use crate::{arch::asm::current::current_pcb, kdebug, syscall::SystemError};
use crate::{kdebug, process::ProcessManager, syscall::SystemError};

use super::wait_queue::WaitQueue;

Expand Down Expand Up @@ -47,11 +47,11 @@ impl Semaphore {
self.counter.fetch_add(1, Ordering::Release);
} else {
//尝试唤醒
if !self.wait_queue.wakeup(0x_ffff_ffff_ffff_ffff) {
if !self.wait_queue.wakeup(None) {
//如果唤醒失败,打印错误信息
kdebug!(
"Semaphore wakeup failed: current pid= {}, semaphore={:?}",
current_pcb().pid,
ProcessManager::current_pcb().basic().pid().into(),
self
);
}
Expand Down
78 changes: 36 additions & 42 deletions kernel/src/libs/wait_queue.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
#![allow(dead_code)]
use alloc::{collections::LinkedList, vec::Vec};
use alloc::{collections::LinkedList, sync::Arc, vec::Vec};

use crate::{
arch::{asm::current::current_pcb, sched::sched, CurrentIrqArch},
arch::{sched::sched, CurrentIrqArch},
exception::InterruptArch,
include::bindings::bindings::{
process_control_block, process_wakeup, PROC_INTERRUPTIBLE, PROC_UNINTERRUPTIBLE,
},
process::{ProcessControlBlock, ProcessManager, ProcessState},
};

use super::{
Expand All @@ -17,7 +15,7 @@ use super::{
#[derive(Debug)]
struct InnerWaitQueue {
/// 等待队列的链表
wait_list: LinkedList<&'static mut process_control_block>,
wait_list: LinkedList<Arc<ProcessControlBlock>>,
}

/// 被自旋锁保护的等待队列
Expand All @@ -30,10 +28,9 @@ impl WaitQueue {
/// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断
pub fn sleep(&self) {
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
current_pcb().state = PROC_INTERRUPTIBLE as u64;
guard.wait_list.push_back(current_pcb());
ProcessManager::sleep(true);
guard.wait_list.push_back(ProcessManager::current_pcb());
drop(guard);

sched();
}

Expand All @@ -43,8 +40,8 @@ impl WaitQueue {
F: FnOnce(),
{
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
current_pcb().state = PROC_INTERRUPTIBLE as u64;
guard.wait_list.push_back(current_pcb());
ProcessManager::sleep(true);
guard.wait_list.push_back(ProcessManager::current_pcb());
f();
drop(guard);
sched();
Expand All @@ -68,15 +65,15 @@ impl WaitQueue {
// 安全检查:确保当前处于中断禁止状态
assert!(CurrentIrqArch::is_irq_enabled() == false);
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
current_pcb().state = PROC_INTERRUPTIBLE as u64;
guard.wait_list.push_back(current_pcb());
ProcessManager::sleep(true);
guard.wait_list.push_back(ProcessManager::current_pcb());
drop(guard);
}
/// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断
pub fn sleep_uninterruptible(&self) {
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
current_pcb().state = PROC_UNINTERRUPTIBLE as u64;
guard.wait_list.push_back(current_pcb());
ProcessManager::sleep(false);
guard.wait_list.push_back(ProcessManager::current_pcb());
drop(guard);
sched();
}
Expand All @@ -85,8 +82,8 @@ impl WaitQueue {
/// 在当前进程的pcb加入队列后,解锁指定的自旋锁。
pub fn sleep_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) {
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
current_pcb().state = PROC_INTERRUPTIBLE as u64;
guard.wait_list.push_back(current_pcb());
ProcessManager::sleep(true);
guard.wait_list.push_back(ProcessManager::current_pcb());
drop(to_unlock);
drop(guard);
sched();
Expand All @@ -96,8 +93,8 @@ impl WaitQueue {
/// 在当前进程的pcb加入队列后,解锁指定的Mutex。
pub fn sleep_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) {
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
current_pcb().state = PROC_INTERRUPTIBLE as u64;
guard.wait_list.push_back(current_pcb());
ProcessManager::sleep(true);
guard.wait_list.push_back(ProcessManager::current_pcb());
drop(to_unlock);
drop(guard);
sched();
Expand All @@ -107,8 +104,8 @@ impl WaitQueue {
/// 在当前进程的pcb加入队列后,解锁指定的自旋锁。
pub fn sleep_uninterruptible_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) {
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
current_pcb().state = PROC_UNINTERRUPTIBLE as u64;
guard.wait_list.push_back(current_pcb());
ProcessManager::sleep(false);
guard.wait_list.push_back(ProcessManager::current_pcb());
drop(to_unlock);
drop(guard);
sched();
Expand All @@ -118,8 +115,8 @@ impl WaitQueue {
/// 在当前进程的pcb加入队列后,解锁指定的Mutex。
pub fn sleep_uninterruptible_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) {
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
current_pcb().state = PROC_UNINTERRUPTIBLE as u64;
guard.wait_list.push_back(current_pcb());
ProcessManager::sleep(false);
guard.wait_list.push_back(ProcessManager::current_pcb());
drop(to_unlock);
drop(guard);
sched();
Expand All @@ -128,51 +125,48 @@ impl WaitQueue {
/// @brief 唤醒在队列中等待的第一个进程。
/// 如果这个进程的state与给定的state进行and操作之后,结果不为0,则唤醒它。
///
/// @param state 用于判断的state,如果队列中第一个进程的state与它进行and操作之后,结果不为0,则唤醒这个进程。
/// @param state 用于判断的state,如果队列第一个进程与这个state相同,或者为None(表示不进行这个判断),则唤醒这个进程。
///
/// @return true 成功唤醒进程
/// @return false 没有唤醒进程
pub fn wakeup(&self, state: u64) -> bool {
pub fn wakeup(&self, state: Option<ProcessState>) -> bool {
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
// 如果队列为空,则返回
if guard.wait_list.is_empty() {
return false;
}

// 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒
if (guard.wait_list.front().unwrap().state & state) != 0 {
let to_wakeup = guard.wait_list.pop_front().unwrap();
unsafe {
process_wakeup(to_wakeup);
if let Some(state) = state {
if guard.wait_list.front().unwrap().sched_info().state() != state {
return false;
}
return true;
} else {
return false;
}
let to_wakeup = guard.wait_list.pop_front().unwrap();
ProcessManager::wakeup(&to_wakeup);
return true;
}

/// @brief 唤醒在队列中,符合条件的所有进程。
///
/// @param state 用于判断的state,如果队列中第一个进程的state与它进行and操作之后,结果不为0,则唤醒这个进程。
pub fn wakeup_all(&self, state: u64) {
/// @param state 用于判断的state,如果一个进程与这个state相同,或者为None(表示不进行这个判断),则唤醒这个进程。
pub fn wakeup_all(&self, state: Option<ProcessState>) {
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave();
// 如果队列为空,则返回
if guard.wait_list.is_empty() {
return;
}

let mut to_push_back: Vec<&mut process_control_block> = Vec::new();
let mut to_push_back: Vec<Arc<ProcessControlBlock>> = Vec::new();
// 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒
while let Some(to_wakeup) = guard.wait_list.pop_front() {
if (to_wakeup.state & state) != 0 {
unsafe {
process_wakeup(to_wakeup);
if let Some(state) = state {
if to_wakeup.sched_info().state() != state {
ProcessManager::wakeup(&to_wakeup);
continue;
}
} else {
to_push_back.push(to_wakeup);
}
to_push_back.push(to_wakeup);
}

for to_wakeup in to_push_back {
guard.wait_list.push_back(to_wakeup);
}
Expand Down
4 changes: 2 additions & 2 deletions kernel/src/net/net_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ pub fn poll_ifaces() {
for (_, iface) in guard.iter() {
iface.poll(&mut sockets).ok();
}
SOCKET_WAITQUEUE.wakeup_all((-1i64) as u64);
SOCKET_WAITQUEUE.wakeup_all(None);
}

/// 对ifaces进行轮询,最多对SOCKET_SET尝试times次加锁。
Expand Down Expand Up @@ -154,7 +154,7 @@ pub fn poll_ifaces_try_lock(times: u16) -> Result<(), SystemError> {
for (_, iface) in guard.iter() {
iface.poll(&mut sockets).ok();
}
SOCKET_WAITQUEUE.wakeup_all((-1i64) as u64);
SOCKET_WAITQUEUE.wakeup_all(None);
return Ok(());
}

Expand Down
2 changes: 1 addition & 1 deletion kernel/src/process/kthread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ impl KernelThreadMechanism {
list = KTHREAD_CREATE_LIST.lock();
}
drop(list);
ProcessManager::sleep().ok();
ProcessManager::sleep(true).ok();
}
}
}
Expand Down
15 changes: 11 additions & 4 deletions kernel/src/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use alloc::{
use hashbrown::HashMap;

use crate::{
arch::{asm::current::current_pcb, process::ArchPCBInfo},
arch::process::ArchPCBInfo,
filesystem::vfs::{file::FileDescriptorVec, FileType},
include::bindings::bindings::CLONE_SIGNAL,
kdebug,
Expand All @@ -34,7 +34,10 @@ use crate::{
init::initial_kernel_thread,
kthread::{KernelThreadClosure, KernelThreadCreateInfo, KernelThreadMechanism},
},
sched::{core::CPU_EXECUTING, SchedPolicy, SchedPriority},
sched::{
core::{sched_enqueue, CPU_EXECUTING},
SchedPolicy, SchedPriority,
},
smp::kick_cpu,
syscall::SystemError,
};
Expand Down Expand Up @@ -153,11 +156,15 @@ impl ProcessManager {

/// 唤醒一个进程
pub fn wakeup(pcb: &Arc<ProcessControlBlock>) -> Result<(), SystemError> {
todo!()
if pcb.sched_info().state() != ProcessState::Runnable {
sched_enqueue(pcb.clone(), true);
return Ok(());
}
return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
}

/// 标志当前进程永久睡眠,移出调度队列
pub fn sleep() -> Result<(), SystemError> {
pub fn sleep(interruptable: bool) -> Result<(), SystemError> {
todo!()
}

Expand Down

0 comments on commit 9586833

Please sign in to comment.