diff --git a/Makefile b/Makefile index 81a90e65..7c240815 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,7 @@ TEST_DIR := ./testcase/$(TEST) export STRACE := export SMP := export PREEMPT := +export DEBUG := # Args DISASM_ARGS = -d diff --git a/arch/src/riscv64/sstatus.rs b/arch/src/riscv64/sstatus.rs index 9941347c..c20553cd 100644 --- a/arch/src/riscv64/sstatus.rs +++ b/arch/src/riscv64/sstatus.rs @@ -24,6 +24,10 @@ impl Sstatus { } } + pub fn sie(&mut self) -> bool { + self.bits.get_bit(1) + } + pub fn set_spie(&mut self, val: bool) { self.bits.set_bit(5, val); } diff --git a/kernel/Makefile b/kernel/Makefile index 366b7ce6..b24892d5 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -9,6 +9,9 @@ endif ifneq ($(PREEMPT), ) FEATURES += preempt endif +ifneq ($(DEBUG), ) + FEATURES += debug +endif CARGO_BUILD_ARGS := ifeq ($(MODE), release) diff --git a/kernel/src/syscall/time.rs b/kernel/src/syscall/time.rs index a6e9f36f..f3873c7e 100644 --- a/kernel/src/syscall/time.rs +++ b/kernel/src/syscall/time.rs @@ -173,7 +173,7 @@ impl Syscall<'_> { return Ok(0); } let sleep = req - current; - task.suspend_timeout(req).await + task.suspend_timeout(sleep).await } else { task.suspend_timeout(req).await }; diff --git a/kernel/src/task/schedule.rs b/kernel/src/task/schedule.rs index 04df8cb8..30f10b4a 100644 --- a/kernel/src/task/schedule.rs +++ b/kernel/src/task/schedule.rs @@ -79,6 +79,12 @@ impl + Send + 'static> Future for KernelTaskFuture { pub async fn task_loop(task: Arc) { *task.waker() = Some(get_waker().await); loop { + match task.state() { + Zombie => break, + Stopped => suspend_now().await, + _ => {} + } + trap::user_trap::trap_return(&task); // task may be set to zombie by other task, e.g. execve will kill other tasks in diff --git a/kernel/src/trap/user_trap.rs b/kernel/src/trap/user_trap.rs index f2558bac..f9a2092a 100644 --- a/kernel/src/trap/user_trap.rs +++ b/kernel/src/trap/user_trap.rs @@ -162,6 +162,8 @@ pub fn trap_return(task: &Arc) { // 2. This task encounter a signal handler task.trap_context_mut().user_fx.restore(); task.trap_context_mut().sstatus.set_fs(FS::Clean); + assert!(!task.trap_context_mut().sstatus.sie()); + assert!(!task.is_zombie()); unsafe { __return_to_user(task.trap_context_mut()); // NOTE: next time when user traps into kernel, it will come back here