From b7b843beddea12cdedda90f6129b7c9980876112 Mon Sep 17 00:00:00 2001 From: GnoCiYeH Date: Mon, 9 Oct 2023 00:58:08 +0800 Subject: [PATCH] =?UTF-8?q?wait4=E7=B3=BB=E7=BB=9F=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E6=94=AF=E6=8C=81options=E5=AD=97=E6=AE=B5=20(#398)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cache-toolchain.yml | 4 +- .github/workflows/rustfmt.yml | 10 +---- kernel/src/driver/acpi/acpi.c | 9 ++-- kernel/src/process/abi.rs | 14 +++++++ kernel/src/process/syscall.rs | 60 ++++++++++++++++++++------- 5 files changed, 69 insertions(+), 28 deletions(-) diff --git a/.github/workflows/cache-toolchain.yml b/.github/workflows/cache-toolchain.yml index dec8dcee..e783c8dd 100644 --- a/.github/workflows/cache-toolchain.yml +++ b/.github/workflows/cache-toolchain.yml @@ -53,5 +53,7 @@ jobs: rustup target add x86_64-unknown-none rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu rustup component add rustfmt + rustup component add rustfmt --toolchain nightly-2023-01-21-x86_64-unknown-linux-gnu + rustup component add rustfmt --toolchain nightly-2023-08-15-x86_64-unknown-linux-gnu cargo install dadk --version 0.1.2 - + diff --git a/.github/workflows/rustfmt.yml b/.github/workflows/rustfmt.yml index 01c8e044..0cb6e848 100644 --- a/.github/workflows/rustfmt.yml +++ b/.github/workflows/rustfmt.yml @@ -1,14 +1,6 @@ name: Rust format check -on: - workflow_run: - workflows: [Build Check] - types: - - completed - - push: - - pull_request: +on: [push, pull_request] jobs: # ensure the toolchain is cached diff --git a/kernel/src/driver/acpi/acpi.c b/kernel/src/driver/acpi/acpi.c index 7d6d4eeb..632941a8 100644 --- a/kernel/src/driver/acpi/acpi.c +++ b/kernel/src/driver/acpi/acpi.c @@ -137,14 +137,15 @@ void acpi_init() multiboot2_iter(multiboot2_get_acpi_old_RSDP, &old_acpi, &reserved); rsdpv1 = &(old_acpi.rsdp); - multiboot2_iter(multiboot2_get_acpi_new_RSDP, &new_acpi, &reserved); - rsdpv2 = &(new_acpi.rsdp); - + // 这里有bug:当multiboot2不存在rsdpv2的时候,会导致错误 + // multiboot2_iter(multiboot2_get_acpi_new_RSDP, &new_acpi, &reserved); + // rsdpv2 = &(new_acpi.rsdp); + rsdpv2 = NULL; rs_acpi_init((uint64_t)rsdpv1); uint64_t paddr = 0; // An ACPI-compatible OS must use the XSDT if present - if (rsdpv2->XsdtAddress != 0x00UL) + if (rsdpv2 && rsdpv2->XsdtAddress != 0x00UL) { // 不要删除这段注释(因为还不确定是代码的bug,还是真机的bug) /* diff --git a/kernel/src/process/abi.rs b/kernel/src/process/abi.rs index 58a7d8ab..cbaab9d0 100644 --- a/kernel/src/process/abi.rs +++ b/kernel/src/process/abi.rs @@ -84,3 +84,17 @@ impl TryFrom for AtType { } } } + +bitflags! { + pub struct WaitOption: u32{ + const WNOHANG = 0x00000001; + const WUNTRACED = 0x00000002; + const WSTOPPED = 0x00000002; + const WEXITED = 0x00000004; + const WCONTINUED = 0x00000008; + const WNOWAIT = 0x01000000; + const WNOTHREAD = 0x20000000; + const WALL = 0x40000000; + const WCLONE = 0x80000000; + } +} diff --git a/kernel/src/process/syscall.rs b/kernel/src/process/syscall.rs index 08f72160..88d62fcb 100644 --- a/kernel/src/process/syscall.rs +++ b/kernel/src/process/syscall.rs @@ -2,7 +2,7 @@ use core::ffi::c_void; use alloc::{string::String, vec::Vec}; -use super::{fork::CloneFlags, Pid, ProcessManager, ProcessState}; +use super::{abi::WaitOption, fork::CloneFlags, Pid, ProcessManager, ProcessState}; use crate::{ arch::{interrupt::TrapFrame, sched::sched, CurrentIrqArch}, exception::InterruptArch, @@ -76,17 +76,20 @@ impl Syscall { options: i32, rusage: *mut c_void, ) -> Result { + let ret = WaitOption::from_bits(options as u32); + let options = match ret { + Some(options) => options, + None => { + return Err(SystemError::EINVAL); + } + }; + let mut _rusage_buf = UserBufferReader::new::(rusage, core::mem::size_of::(), true)?; let mut wstatus_buf = UserBufferWriter::new::(wstatus, core::mem::size_of::(), true)?; - // 暂时不支持options选项 - if options != 0 { - return Err(SystemError::EINVAL); - } - let cur_pcb = ProcessManager::current_pcb(); let rd_childen = cur_pcb.children.read(); @@ -95,15 +98,44 @@ impl Syscall { let child_pcb = rd_childen.get(&pid).ok_or(SystemError::ECHILD)?.clone(); drop(rd_childen); - // 获取退出码 - if let ProcessState::Exited(status) = child_pcb.sched_info().state() { - if !wstatus.is_null() { - wstatus_buf.copy_one_to_user(&status, 0)?; - } - return Ok(pid.into()); + loop { + // 获取退出码 + match child_pcb.sched_info().state() { + ProcessState::Runnable => { + if options.contains(WaitOption::WNOHANG) + || options.contains(WaitOption::WNOWAIT) + { + if !wstatus.is_null() { + wstatus_buf.copy_one_to_user(&WaitOption::WCONTINUED.bits(), 0)?; + } + return Ok(0); + } + } + ProcessState::Blocked(_) => { + // 指定WUNTRACED则等待暂停的进程,不指定则返回0 + if !options.contains(WaitOption::WUNTRACED) + || options.contains(WaitOption::WNOWAIT) + { + if !wstatus.is_null() { + wstatus_buf.copy_one_to_user(&WaitOption::WSTOPPED.bits(), 0)?; + } + return Ok(0); + } + } + ProcessState::Exited(status) => { + if !wstatus.is_null() { + wstatus_buf.copy_one_to_user( + &(status | WaitOption::WEXITED.bits() as usize), + 0, + )?; + } + return Ok(pid.into()); + } + }; + + // 等待指定进程 + child_pcb.wait_queue.sleep(); } - // 等待指定进程 - child_pcb.wait_queue.sleep(); } else if pid < -1 { // TODO 判断是否pgid == -pid(等待指定组任意进程) // 暂时不支持