Browse Source

wait4系统调用支持options字段 (#398)

GnoCiYeH 1 year ago
parent
commit
b7b843bedd

+ 3 - 1
.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
-        
+

+ 1 - 9
.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

+ 5 - 4
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)
         /*

+ 14 - 0
kernel/src/process/abi.rs

@@ -84,3 +84,17 @@ impl TryFrom<u32> 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;
+    }
+}

+ 46 - 14
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<usize, SystemError> {
+        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::<c_void>(rusage, core::mem::size_of::<c_void>(), true)?;
 
         let mut wstatus_buf =
             UserBufferWriter::new::<i32>(wstatus, core::mem::size_of::<i32>(), 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(等待指定组任意进程)
             // 暂时不支持