diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index 2fb99d93..49281026 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -6,6 +6,7 @@ const SYSCALL_READ: usize = 63; const SYSCALL_WRITE: usize = 64; const SYSCALL_EXIT: usize = 93; const SYSCALL_YIELD: usize = 124; +const SYSCALL_KILL: usize = 129; const SYSCALL_GET_TIME: usize = 169; const SYSCALL_GETPID: usize = 172; const SYSCALL_FORK: usize = 220; @@ -28,6 +29,7 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]), SYSCALL_EXIT => sys_exit(args[0] as i32), SYSCALL_YIELD => sys_yield(), + SYSCALL_KILL => sys_kill(args[0], args[1] as u32), SYSCALL_GET_TIME => sys_get_time(), SYSCALL_GETPID => sys_getpid(), SYSCALL_FORK => sys_fork(), diff --git a/os/src/syscall/process.rs b/os/src/syscall/process.rs index 61a9a0ea..795ea3b7 100644 --- a/os/src/syscall/process.rs +++ b/os/src/syscall/process.rs @@ -1,8 +1,8 @@ use crate::fs::{open_file, OpenFlags}; use crate::mm::{translated_ref, translated_refmut, translated_str}; use crate::task::{ - add_task, current_task, current_user_token, exit_current_and_run_next, - suspend_current_and_run_next, + add_task, current_task, current_user_token, exit_current_and_run_next, pid2task, + suspend_current_and_run_next, SignalFlags, }; use crate::timer::get_time_ms; use alloc::string::String; @@ -104,3 +104,16 @@ pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize { } // ---- release current PCB automatically } + +pub fn sys_kill(pid: usize, signal: u32) -> isize { + if let Some(task) = pid2task(pid) { + if let Some(flag) = SignalFlags::from_bits(signal) { + task.inner_exclusive_access().signals |= flag; + 0 + } else { + -1 + } + } else { + -1 + } +} diff --git a/os/src/task/manager.rs b/os/src/task/manager.rs index 542a0b87..e1995a20 100644 --- a/os/src/task/manager.rs +++ b/os/src/task/manager.rs @@ -1,6 +1,6 @@ use super::TaskControlBlock; use crate::sync::UPSafeCell; -use alloc::collections::VecDeque; +use alloc::collections::{BTreeMap, VecDeque}; use alloc::sync::Arc; use lazy_static::*; @@ -26,12 +26,29 @@ impl TaskManager { lazy_static! { pub static ref TASK_MANAGER: UPSafeCell = unsafe { UPSafeCell::new(TaskManager::new()) }; + pub static ref PID2TCB: UPSafeCell>> = + unsafe { UPSafeCell::new(BTreeMap::new()) }; } pub fn add_task(task: Arc) { + PID2TCB + .exclusive_access() + .insert(task.getpid(), Arc::clone(&task)); TASK_MANAGER.exclusive_access().add(task); } pub fn fetch_task() -> Option> { TASK_MANAGER.exclusive_access().fetch() } + +pub fn pid2task(pid: usize) -> Option> { + let map = PID2TCB.exclusive_access(); + map.get(&pid).map(|task| Arc::clone(task)) +} + +pub fn remove_from_pid2task(pid: usize) { + let mut map = PID2TCB.exclusive_access(); + if map.remove(&pid).is_none() { + panic!("cannot find pid {} in pid2task!", pid); + } +} diff --git a/os/src/task/mod.rs b/os/src/task/mod.rs index ebb07b47..cd13f076 100644 --- a/os/src/task/mod.rs +++ b/os/src/task/mod.rs @@ -11,10 +11,11 @@ use alloc::sync::Arc; pub use context::TaskContext; use lazy_static::*; use manager::fetch_task; +use manager::remove_from_pid2task; use switch::__switch; use task::{TaskControlBlock, TaskStatus}; -pub use manager::add_task; +pub use manager::{add_task, pid2task}; pub use pid::{pid_alloc, KernelStack, PidHandle}; pub use processor::{ current_task, current_trap_cx, current_user_token, run_tasks, schedule, take_current_task, @@ -42,6 +43,8 @@ pub fn suspend_current_and_run_next() { pub fn exit_current_and_run_next(exit_code: i32) { // take from Processor let task = take_current_task().unwrap(); + // remove from pid2task + remove_from_pid2task(task.getpid()); // **** access current TCB exclusively let mut inner = task.inner_exclusive_access(); // Change status to Zombie diff --git a/os/src/task/signal.rs b/os/src/task/signal.rs index 2da01399..46f1ad9d 100644 --- a/os/src/task/signal.rs +++ b/os/src/task/signal.rs @@ -3,7 +3,7 @@ use bitflags::*; bitflags! { pub struct SignalFlags: u32 { const SIGINT = 1 << 2; - const SIGILL = 1 << 4; + const SIGILL = 1 << 4; const SIGABRT = 1 << 6; const SIGFPE = 1 << 8; const SIGSEGV = 1 << 11; diff --git a/os/src/trap/mod.rs b/os/src/trap/mod.rs index eb534b85..05c36b89 100644 --- a/os/src/trap/mod.rs +++ b/os/src/trap/mod.rs @@ -3,7 +3,8 @@ mod context; use crate::config::{TRAMPOLINE, TRAP_CONTEXT}; use crate::syscall::syscall; use crate::task::{ - current_trap_cx, current_user_token, exit_current_and_run_next, suspend_current_and_run_next, current_add_signal, SignalFlags, check_signals_of_current, + check_signals_of_current, current_add_signal, current_trap_cx, current_user_token, + exit_current_and_run_next, suspend_current_and_run_next, SignalFlags, }; use crate::timer::set_next_trigger; use core::arch::{asm, global_asm}; diff --git a/user/src/lang_items.rs b/user/src/lang_items.rs index c65aa421..df0467c3 100644 --- a/user/src/lang_items.rs +++ b/user/src/lang_items.rs @@ -1,4 +1,4 @@ -use super::exit; +use super::{getpid, kill, SignalFlags}; #[panic_handler] fn panic_handler(panic_info: &core::panic::PanicInfo) -> ! { @@ -13,5 +13,6 @@ fn panic_handler(panic_info: &core::panic::PanicInfo) -> ! { } else { println!("Panicked: {}", err); } - exit(-1); + kill(getpid() as usize, SignalFlags::SIGABRT.bits()); + unreachable!() } diff --git a/user/src/lib.rs b/user/src/lib.rs index 84821ec5..f15d9ce7 100644 --- a/user/src/lib.rs +++ b/user/src/lib.rs @@ -127,9 +127,28 @@ pub fn waitpid(pid: usize, exit_code: &mut i32) -> isize { } } } + +pub fn waitpid_nb(pid: usize, exit_code: &mut i32) -> isize { + sys_waitpid(pid as isize, exit_code as *mut _) +} + pub fn sleep(period_ms: usize) { let start = sys_get_time(); while sys_get_time() < start + period_ms as isize { sys_yield(); } } + +bitflags! { + pub struct SignalFlags: i32 { + const SIGINT = 1 << 2; + const SIGILL = 1 << 4; + const SIGABRT = 1 << 6; + const SIGFPE = 1 << 8; + const SIGSEGV = 1 << 11; + } +} + +pub fn kill(pid: usize, signal: i32) -> isize { + sys_kill(pid, signal) +} diff --git a/user/src/syscall.rs b/user/src/syscall.rs index e1e8a100..1481de68 100644 --- a/user/src/syscall.rs +++ b/user/src/syscall.rs @@ -8,6 +8,7 @@ const SYSCALL_READ: usize = 63; const SYSCALL_WRITE: usize = 64; const SYSCALL_EXIT: usize = 93; const SYSCALL_YIELD: usize = 124; +const SYSCALL_KILL: usize = 129; const SYSCALL_GET_TIME: usize = 169; const SYSCALL_GETPID: usize = 172; const SYSCALL_FORK: usize = 220; @@ -64,6 +65,10 @@ pub fn sys_yield() -> isize { syscall(SYSCALL_YIELD, [0, 0, 0]) } +pub fn sys_kill(pid: usize, signal: i32) -> isize { + syscall(SYSCALL_KILL, [pid, signal as usize, 0]) +} + pub fn sys_get_time() -> isize { syscall(SYSCALL_GET_TIME, [0, 0, 0]) }