diff --git a/kernel-src/include/kernel/scheduler.h b/kernel-src/include/kernel/scheduler.h index 4044a916..f7852832 100644 --- a/kernel-src/include/kernel/scheduler.h +++ b/kernel-src/include/kernel/scheduler.h @@ -155,5 +155,6 @@ void sched_targetcpu(struct cpu_t *cpu); void sched_sleepus(size_t us); void sched_apentry(); void sched_inactiveproc(proc_t *proc); +void sched_terminateprogram(int status); #endif diff --git a/kernel-src/sys/scheduler.c b/kernel-src/sys/scheduler.c index 9b3af8dc..6942a91c 100644 --- a/kernel-src/sys/scheduler.c +++ b/kernel-src/sys/scheduler.c @@ -407,6 +407,19 @@ void sched_stopotherthreads() { proc->nomorethreads = false; } +void sched_terminateprogram(int status) { + thread_t *thread = _cpu()->thread; + proc_t *proc = thread->proc; + if (spinlock_try(&proc->exiting) == false) + sched_threadexit(); + + sched_stopotherthreads(); + + proc->status = status; + + sched_threadexit(); +} + static void yield(context_t *context) { thread_t *thread = _cpu()->thread; diff --git a/kernel-src/sys/signal.c b/kernel-src/sys/signal.c index 7d204f77..f8ce7076 100644 --- a/kernel-src/sys/signal.c +++ b/kernel-src/sys/signal.c @@ -253,12 +253,10 @@ bool signal_check(struct thread_t *thread, context_t *context, bool syscall, uin THREAD_ENTER(thread); if (SIGNAL_GET(&proc->signals.pending, SIGKILL) || SIGNAL_GET(&thread->signals.pending, SIGKILL)) { - // TODO terminate entire program THREAD_LEAVE(thread); PROCESS_LEAVE(proc); - proc->status = SIGKILL; interrupt_set(true); - sched_threadexit(); + sched_terminateprogram(SIGKILL); } // find the first pending signal which is unmasked @@ -312,12 +310,10 @@ bool signal_check(struct thread_t *thread, context_t *context, bool syscall, uin goto leave; case ACTION_CORE: case ACTION_TERM: - // TODO terminate entire program - proc->status = signal; THREAD_LEAVE(thread); PROCESS_LEAVE(proc); interrupt_set(true); - sched_threadexit(); + sched_terminateprogram(signal); case ACTION_STOP: // TODO what if a thread unmasks a stop signal? // check if sigcont is not pending for the thread (SIGCONT is always sent to the thread) diff --git a/kernel-src/sys/syscalls/exit.c b/kernel-src/sys/syscalls/exit.c index aa46b454..aa5033c8 100644 --- a/kernel-src/sys/syscalls/exit.c +++ b/kernel-src/sys/syscalls/exit.c @@ -6,14 +6,6 @@ #include __attribute__((noreturn)) void syscall_exit(context_t *context, int status) { - thread_t *thread = _cpu()->thread; - proc_t *proc = thread->proc; - if (spinlock_try(&proc->exiting) == false) - sched_threadexit(); - - sched_stopotherthreads(); - - proc->status = status << 8; - - sched_threadexit(); + sched_terminateprogram(status << 8); + __builtin_unreachable(); }