Support signal mechanism for ch8(only works on signal-thread apps)

This commit is contained in:
Yifan Wu 2022-01-23 13:14:56 -08:00
parent 59f13cb536
commit 26bc01f3bc
17 changed files with 235 additions and 17 deletions

View file

@ -15,7 +15,7 @@ pub fn main(argc: usize, argv: &[&str]) -> i32 {
panic!("Error occured when opening file");
}
let fd = fd as usize;
let mut buf = [0u8; 16];
let mut buf = [0u8; 256];
loop {
let size = read(fd, &mut buf) as usize;
if size == 0 {

10
user/src/bin/infloop.rs Normal file
View file

@ -0,0 +1,10 @@
#![no_std]
#![no_main]
#![allow(clippy::empty_loop)]
extern crate user_lib;
#[no_mangle]
pub fn main(_argc: usize, _argv: &[&str]) -> ! {
loop {}
}

17
user/src/bin/priv_csr.rs Normal file
View file

@ -0,0 +1,17 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
use riscv::register::sstatus::{self, SPP};
#[no_mangle]
fn main() -> i32 {
println!("Try to access privileged CSR in U Mode");
println!("Kernel should kill this application!");
unsafe {
sstatus::set_spp(SPP::User);
}
0
}

17
user/src/bin/priv_inst.rs Normal file
View file

@ -0,0 +1,17 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
use core::arch::asm;
#[no_mangle]
fn main() -> i32 {
println!("Try to execute privileged instruction in U Mode");
println!("Kernel should kill this application!");
unsafe {
asm!("sret");
}
0
}

View file

@ -0,0 +1,15 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
#[no_mangle]
fn main() -> i32 {
println!("Into Test store_fault, we will insert an invalid store operation...");
println!("Kernel should kill this application!");
unsafe {
core::ptr::null_mut::<u8>().write_volatile(0);
}
0
}

View file

@ -0,0 +1,46 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
use user_lib::{exec, fork, get_time, kill, waitpid, waitpid_nb, SignalFlags};
#[no_mangle]
pub fn main(argc: usize, argv: &[&str]) -> i32 {
assert_eq!(argc, 3, "argc must be 3!");
let timeout_ms = argv[2]
.parse::<isize>()
.expect("Error when parsing timeout!");
let pid = fork() as usize;
if pid == 0 {
if exec(argv[1], &[core::ptr::null::<u8>()]) != 0 {
println!("Error when executing '{}'", argv[1]);
return -4;
}
} else {
let start_time = get_time();
let mut child_exited = false;
let mut exit_code: i32 = 0;
loop {
if get_time() - start_time > timeout_ms {
break;
}
if waitpid_nb(pid, &mut exit_code) as usize == pid {
child_exited = true;
println!(
"child exited in {}ms, exit_code = {}",
get_time() - start_time,
exit_code,
);
}
}
if !child_exited {
println!("child has run for {}ms, kill it!", timeout_ms);
kill(pid, SignalFlags::SIGINT.bits());
assert_eq!(waitpid(pid, &mut exit_code) as usize, pid);
println!("exit code of the child is {}", exit_code);
}
}
0
}

View file

@ -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!()
}

View file

@ -127,6 +127,25 @@ 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 _)
}
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)
}
pub fn sleep(sleep_ms: usize) {
sys_sleep(sleep_ms);
}

View file

@ -9,6 +9,7 @@ const SYSCALL_WRITE: usize = 64;
const SYSCALL_EXIT: usize = 93;
const SYSCALL_SLEEP: usize = 101;
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;
@ -81,6 +82,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])
}