From e1d5b7e7b40b828253e50e12f27357fef752a927 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 28 Oct 2023 15:15:32 +0200 Subject: [PATCH] kernel: Implement thread stopping and continuing --- kernel/src/thread/Thread.cpp | 19 +++++++++++++++++-- kernel/src/thread/Thread.h | 4 ++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/kernel/src/thread/Thread.cpp b/kernel/src/thread/Thread.cpp index 6d092515..c3514560 100644 --- a/kernel/src/thread/Thread.cpp +++ b/kernel/src/thread/Thread.cpp @@ -136,6 +136,7 @@ enum class DefaultSignalAction { Ignore, Terminate, + Stop, }; // FIXME: Implement coredumps for some signals. @@ -149,9 +150,9 @@ static constexpr DefaultSignalAction default_actions[] = { DefaultSignalAction::Ignore, // SIGCHLD DefaultSignalAction::Terminate, // SIGFPE (dump core) DefaultSignalAction::Terminate, // SIGKILL - DefaultSignalAction::Terminate, // SIGSTOP (FIXME: Support stopping and continuing) + DefaultSignalAction::Stop, // SIGSTOP DefaultSignalAction::Terminate, // SIGSEGV (dump core) - DefaultSignalAction::Ignore, // SIGCONT (FIXME: Support stopping and continuing) + DefaultSignalAction::Ignore, // SIGCONT (Handled separately) DefaultSignalAction::Terminate, // SIGPIPE DefaultSignalAction::Terminate, // SIGALRM DefaultSignalAction::Terminate, // SIGTERM @@ -193,6 +194,7 @@ void Thread::process_pending_signals(Registers* current_regs) { case DefaultSignalAction::Ignore: return; case DefaultSignalAction::Terminate: exit_and_signal_parent(signo | _SIGBIT); + case DefaultSignalAction::Stop: stop(); default: return; } } @@ -227,12 +229,25 @@ void Thread::send_signal(int signo) if (is_kernel) return; if (state == ThreadState::Exited || state == ThreadState::Dying) return; + if (state == ThreadState::Stopped && signo == SIGCONT) + { + wake_up(); + return; + } + check(signo > 0 && signo <= NSIG); pending_signals.set(signo - 1, true); if (state == ThreadState::Waiting || state == ThreadState::Sleeping || is_in_kernel(®s)) { + if (state == ThreadState::Stopped && signo != SIGKILL) return; interrupted = true; wake_up(); } } + +void Thread::stop() +{ + state = ThreadState::Stopped; + kernel_yield(); +} diff --git a/kernel/src/thread/Thread.h b/kernel/src/thread/Thread.h index 8a9829fe..a46ea73d 100644 --- a/kernel/src/thread/Thread.h +++ b/kernel/src/thread/Thread.h @@ -26,6 +26,7 @@ enum class ThreadState Runnable, Sleeping, Waiting, + Stopped, Exited, Dying }; @@ -152,6 +153,9 @@ struct Thread : public LinkedListNode Result push_mem_on_stack(const u8* mem, usize size); Result pop_mem_from_stack(u8* mem, usize size); + void stop(); + void resume(); + void send_signal(int signo); static void init();