diff --git a/kernel/rustkernel/src/console/mod.rs b/kernel/rustkernel/src/console/mod.rs index 49153de..8e79fa8 100644 --- a/kernel/rustkernel/src/console/mod.rs +++ b/kernel/rustkernel/src/console/mod.rs @@ -13,7 +13,7 @@ pub mod uart; use crate::{ fs::file::{devsw, CONSOLE}, - proc::proc::{killed, procdump, wakeup, Proc}, + proc::proc::{procdump, wakeup, Proc}, sync::mutex::Mutex, }; use core::{ffi::c_void, ptr::addr_of_mut}; @@ -114,7 +114,7 @@ pub fn consoleread(user_dst: i32, mut dst: u64, mut n: i32) -> i32 { // Wait until interrupt handler has put // some input into cons.buffer. while console.read_index == console.write_index { - if killed(addr_of_mut!(*Proc::current().unwrap())) != 0 { + if Proc::current().unwrap().is_killed() { // cons.lock.unlock(); return -1; } diff --git a/kernel/rustkernel/src/io/pipe.rs b/kernel/rustkernel/src/io/pipe.rs index 0b48dc2..e8b0d0d 100644 --- a/kernel/rustkernel/src/io/pipe.rs +++ b/kernel/rustkernel/src/io/pipe.rs @@ -4,7 +4,7 @@ use crate::{ kalloc::{kalloc, kfree}, virtual_memory::{copyin, copyout}, }, - proc::proc::{killed, wakeup, Proc}, + proc::proc::{wakeup, Proc}, sync::spinlock::Spinlock, }; use core::ptr::{addr_of, addr_of_mut}; @@ -92,7 +92,7 @@ impl Pipe { let guard = self.lock.lock(); while i < num_bytes { - if self.is_read_open == 0 || killed(addr_of_mut!(*proc)) > 0 { + if self.is_read_open == 0 || proc.is_killed() { return Err(PipeError::ProcessKilled); } if self.bytes_written == self.bytes_read + PIPESIZE as u32 { @@ -121,7 +121,7 @@ impl Pipe { // DOC: pipe-empty while self.bytes_read == self.bytes_written && self.is_write_open > 0 { - if killed(addr_of_mut!(*proc)) > 0 { + if proc.is_killed() { return Err(PipeError::ProcessKilled); } else { // DOC: piperead-sleep diff --git a/kernel/rustkernel/src/proc/proc.rs b/kernel/rustkernel/src/proc/proc.rs index 9edecad..927ae19 100644 --- a/kernel/rustkernel/src/proc/proc.rs +++ b/kernel/rustkernel/src/proc/proc.rs @@ -125,6 +125,41 @@ impl Proc { unsafe { Some(&mut *p) } } } + /// Kill the process with the given pid. + /// Returns true if the process was killed. + /// The victim won't exit until it tries to return + /// to user space (see usertrap() in trap.c). + pub unsafe fn kill(pid: i32) -> bool { + for p in &mut proc { + let _guard = p.lock.lock(); + + if p.pid == pid { + p.killed = 1; + + if p.state == ProcState::Sleeping { + // Wake process from sleep(). + p.state = ProcState::Runnable; + } + + return true; + } + } + + false + } + + pub fn is_killed(&self) -> bool { + let _guard = self.lock.lock(); + self.killed > 0 + } + pub fn set_killed(&mut self, killed: bool) { + let _guard = self.lock.lock(); + if killed { + self.killed = 1; + } else { + self.killed = 0; + } + } } /// Return the current struct proc *, or zero if none. @@ -260,31 +295,23 @@ pub unsafe fn sleep(chan: *mut c_void) { /// to user space (see usertrap() in trap.c). #[no_mangle] pub unsafe extern "C" fn kill(pid: i32) -> i32 { - for p in &mut proc { - let _guard = p.lock.lock(); - - if p.pid == pid { - p.killed = 1; - - if p.state == ProcState::Sleeping { - // Wake process from sleep(). - p.state = ProcState::Runnable; - } - - return 0; - } + if Proc::kill(pid) { + 1 + } else { + 0 } - -1 } #[no_mangle] pub unsafe extern "C" fn setkilled(p: *mut Proc) { - let _guard = (*p).lock.lock(); - (*p).killed = 1; + (*p).set_killed(true); } #[no_mangle] pub unsafe extern "C" fn killed(p: *mut Proc) -> i32 { - let _guard = (*p).lock.lock(); - (*p).killed + if (*p).is_killed() { + 1 + } else { + 0 + } } diff --git a/kernel/rustkernel/src/syscall.rs b/kernel/rustkernel/src/syscall.rs index 1afa2a7..ecee9d4 100644 --- a/kernel/rustkernel/src/syscall.rs +++ b/kernel/rustkernel/src/syscall.rs @@ -85,7 +85,7 @@ impl Syscall { Syscall::Kill => { let mut pid = 0i32; argint(0, addr_of_mut!(pid)); - proc::kill(pid) as u64 + Proc::kill(pid) as u64 } Syscall::Exec => sys_exec(), Syscall::Fstat => { @@ -157,7 +157,7 @@ impl Syscall { let mut ticks = CLOCK_TICKS.lock_spinning(); while *ticks < *ticks + n as usize { - if proc::killed(addr_of!(*Proc::current().unwrap()).cast_mut()) > 0 { + if Proc::current().unwrap().is_killed() { return -1i64 as u64; } // Sleep until the value changes. diff --git a/kernel/rustkernel/src/trap.rs b/kernel/rustkernel/src/trap.rs index cb4aa53..8c9fd55 100644 --- a/kernel/rustkernel/src/trap.rs +++ b/kernel/rustkernel/src/trap.rs @@ -3,12 +3,12 @@ use crate::{ println, proc::{ cpu::Cpu, - proc::{exit, killed, r#yield, setkilled, wakeup, Proc, ProcState}, + proc::{exit, r#yield, wakeup, Proc, ProcState}, }, sync::mutex::Mutex, syscall::syscall, }; -use core::ptr::{addr_of, addr_of_mut}; +use core::ptr::addr_of; extern "C" { pub fn kernelvec(); @@ -229,8 +229,8 @@ pub unsafe extern "C" fn usertrap() { if r_scause() == 8 { // System call - - if killed(addr_of_mut!(*proc)) > 0 { + + if proc.is_killed() { exit(-1); } @@ -254,10 +254,10 @@ pub unsafe extern "C" fn usertrap() { r_sepc(), r_stval() ); - setkilled(addr_of_mut!(*proc)); + proc.set_killed(true); } - if killed(addr_of_mut!(*proc)) > 0 { + if proc.is_killed() { exit(-1); }