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

@ -1,6 +1,6 @@
use super::TaskControlBlock;
use super::{ProcessControlBlock, TaskControlBlock};
use crate::sync::UPSafeCell;
use alloc::collections::VecDeque;
use alloc::collections::{BTreeMap, VecDeque};
use alloc::sync::Arc;
use lazy_static::*;
@ -26,6 +26,8 @@ impl TaskManager {
lazy_static! {
pub static ref TASK_MANAGER: UPSafeCell<TaskManager> =
unsafe { UPSafeCell::new(TaskManager::new()) };
pub static ref PID2PCB: UPSafeCell<BTreeMap<usize, Arc<ProcessControlBlock>>> =
unsafe { UPSafeCell::new(BTreeMap::new()) };
}
pub fn add_task(task: Arc<TaskControlBlock>) {
@ -35,3 +37,19 @@ pub fn add_task(task: Arc<TaskControlBlock>) {
pub fn fetch_task() -> Option<Arc<TaskControlBlock>> {
TASK_MANAGER.exclusive_access().fetch()
}
pub fn pid2process(pid: usize) -> Option<Arc<ProcessControlBlock>> {
let map = PID2PCB.exclusive_access();
map.get(&pid).map(|task| Arc::clone(task))
}
pub fn insert_into_pid2process(pid: usize, process: Arc<ProcessControlBlock>) {
PID2PCB.exclusive_access().insert(pid, process);
}
pub fn remove_from_pid2process(pid: usize) {
let mut map = PID2PCB.exclusive_access();
if map.remove(&pid).is_none() {
panic!("cannot find pid {} in pid2task!", pid);
}
}

View file

@ -3,6 +3,7 @@ mod id;
mod manager;
mod process;
mod processor;
mod signal;
mod switch;
mod task;
@ -15,11 +16,12 @@ use switch::__switch;
pub use context::TaskContext;
pub use id::{kstack_alloc, pid_alloc, KernelStack, PidHandle};
pub use manager::add_task;
pub use manager::{add_task, pid2process, remove_from_pid2process};
pub use processor::{
current_kstack_top, current_process, current_task, current_trap_cx, current_trap_cx_user_va,
current_user_token, run_tasks, schedule, take_current_task,
};
pub use signal::SignalFlags;
pub use task::{TaskControlBlock, TaskStatus};
pub fn suspend_current_and_run_next() {
@ -64,6 +66,7 @@ pub fn exit_current_and_run_next(exit_code: i32) {
// however, if this is the main thread of current process
// the process should terminate at once
if tid == 0 {
remove_from_pid2process(process.getpid());
let mut process_inner = process.inner_exclusive_access();
// mark this process as a zombie process
process_inner.is_zombie = true;
@ -111,3 +114,15 @@ lazy_static! {
pub fn add_initproc() {
let _initproc = INITPROC.clone();
}
pub fn check_signals_of_current() -> Option<(i32, &'static str)> {
let process = current_process();
let process_inner = process.inner_exclusive_access();
process_inner.signals.check_error()
}
pub fn current_add_signal(signal: SignalFlags) {
let process = current_process();
let mut process_inner = process.inner_exclusive_access();
process_inner.signals |= signal;
}

View file

@ -1,6 +1,7 @@
use super::add_task;
use super::id::RecycleAllocator;
use super::manager::insert_into_pid2process;
use super::TaskControlBlock;
use super::{add_task, SignalFlags};
use super::{pid_alloc, PidHandle};
use crate::fs::{File, Stdin, Stdout};
use crate::mm::{translated_refmut, MemorySet, KERNEL_SPACE};
@ -26,6 +27,7 @@ pub struct ProcessControlBlockInner {
pub children: Vec<Arc<ProcessControlBlock>>,
pub exit_code: i32,
pub fd_table: Vec<Option<Arc<dyn File + Send + Sync>>>,
pub signals: SignalFlags,
pub tasks: Vec<Option<Arc<TaskControlBlock>>>,
pub task_res_allocator: RecycleAllocator,
pub mutex_list: Vec<Option<Arc<dyn Mutex>>>,
@ -92,6 +94,7 @@ impl ProcessControlBlock {
// 2 -> stderr
Some(Arc::new(Stdout)),
],
signals: SignalFlags::empty(),
tasks: Vec::new(),
task_res_allocator: RecycleAllocator::new(),
mutex_list: Vec::new(),
@ -123,6 +126,7 @@ impl ProcessControlBlock {
let mut process_inner = process.inner_exclusive_access();
process_inner.tasks.push(Some(Arc::clone(&task)));
drop(process_inner);
insert_into_pid2process(process.getpid(), Arc::clone(&process));
// add main thread to scheduler
add_task(task);
process
@ -209,6 +213,7 @@ impl ProcessControlBlock {
children: Vec::new(),
exit_code: 0,
fd_table: new_fd_table,
signals: SignalFlags::empty(),
tasks: Vec::new(),
task_res_allocator: RecycleAllocator::new(),
mutex_list: Vec::new(),
@ -242,6 +247,7 @@ impl ProcessControlBlock {
let trap_cx = task_inner.get_trap_cx();
trap_cx.kernel_sp = task.kstack.get_top();
drop(task_inner);
insert_into_pid2process(child.getpid(), Arc::clone(&child));
// add this thread to scheduler
add_task(task);
child

29
os/src/task/signal.rs Normal file
View file

@ -0,0 +1,29 @@
use bitflags::*;
bitflags! {
pub struct SignalFlags: u32 {
const SIGINT = 1 << 2;
const SIGILL = 1 << 4;
const SIGABRT = 1 << 6;
const SIGFPE = 1 << 8;
const SIGSEGV = 1 << 11;
}
}
impl SignalFlags {
pub fn check_error(&self) -> Option<(i32, &'static str)> {
if self.contains(Self::SIGINT) {
Some((-2, "Killed, SIGINT=2"))
} else if self.contains(Self::SIGILL) {
Some((-4, "Illegal Instruction, SIGILL=4"))
} else if self.contains(Self::SIGABRT) {
Some((-6, "Aborted, SIGABRT=6"))
} else if self.contains(Self::SIGFPE) {
Some((-8, "Erroneous Arithmetic Operation, SIGFPE=8"))
} else if self.contains(Self::SIGSEGV) {
Some((-11, "Segmentation Fault, SIGSEGV=11"))
} else {
None
}
}
}