From 96f3d29d37b9f466245bbfeae5afc2c6370443eb Mon Sep 17 00:00:00 2001 From: apio Date: Thu, 4 May 2023 23:06:00 +0200 Subject: [PATCH] kernel: Tell the reap thread to run when it's needed, instead of checking every 200 ms --- kernel/src/main.cpp | 5 +++-- kernel/src/sys/waitpid.cpp | 1 + kernel/src/thread/Scheduler.cpp | 22 +++++++++++++++++----- kernel/src/thread/Scheduler.h | 9 ++++++--- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 94526d68..d7219651 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -30,7 +30,7 @@ void reap_thread() dying_threads.consume([](Thread* thread) { Scheduler::reap_thread(thread); }); - kernel_sleep(250); + kernel_wait(0); } } @@ -56,7 +56,8 @@ Result init() auto init = TRY(VFS::resolve_path("/bin/init", Credentials {})); auto init_thread = TRY(Scheduler::new_userspace_thread(init, "/bin/init")); - Scheduler::new_kernel_thread(reap_thread, "[reap]").release_value(); + auto reap = Scheduler::new_kernel_thread(reap_thread, "[reap]").release_value(); + Scheduler::set_reap_thread(reap); PCI::scan( [](const PCI::Device& device) { diff --git a/kernel/src/sys/waitpid.cpp b/kernel/src/sys/waitpid.cpp index 07073929..20a05e11 100644 --- a/kernel/src/sys/waitpid.cpp +++ b/kernel/src/sys/waitpid.cpp @@ -51,6 +51,7 @@ Result sys_waitpid(Registers*, SyscallArgs args) u64 id = thread->id; thread->state = ThreadState::Dying; + Scheduler::signal_reap_thread(); if (status_ptr) if (!MemoryManager::copy_to_user_typed(status_ptr, &status)) return err(EFAULT); diff --git a/kernel/src/thread/Scheduler.cpp b/kernel/src/thread/Scheduler.cpp index 5d2d317a..8aa5a71a 100644 --- a/kernel/src/thread/Scheduler.cpp +++ b/kernel/src/thread/Scheduler.cpp @@ -12,6 +12,7 @@ static Thread g_idle; static Thread* g_current = nullptr; static Thread* g_init = nullptr; +static Thread* g_reap = nullptr; static const usize TICKS_PER_TIMESLICE = 20; @@ -58,7 +59,17 @@ namespace Scheduler return g_init; } - Result new_kernel_thread_impl(Thread* thread, const char* name) + void set_reap_thread(Thread* thread) + { + g_reap = thread; + } + + void signal_reap_thread() + { + if (g_reap) g_reap->state = ThreadState::Runnable; + } + + Result new_kernel_thread_impl(Thread* thread, const char* name) { // If anything fails, make sure to clean up. auto guard = make_scope_guard([&] { delete thread; }); @@ -84,10 +95,10 @@ namespace Scheduler kinfoln("Created kernel thread: id %lu with ip %#lx and sp %#lx", thread->id, thread->ip(), thread->sp()); - return {}; + return thread; } - Result new_kernel_thread(u64 address, const char* name) + Result new_kernel_thread(u64 address, const char* name) { Thread* const thread = TRY(new_thread()); thread->init_regs_kernel(); @@ -96,7 +107,7 @@ namespace Scheduler return new_kernel_thread_impl(thread, name); } - Result new_kernel_thread(void (*func)(void), const char* name) + Result new_kernel_thread(void (*func)(void), const char* name) { Thread* const thread = TRY(new_thread()); thread->init_regs_kernel(); @@ -105,7 +116,7 @@ namespace Scheduler return new_kernel_thread_impl(thread, name); } - Result new_kernel_thread(void (*func)(void*), void* arg, const char* name) + Result new_kernel_thread(void (*func)(void*), void* arg, const char* name) { Thread* const thread = TRY(new_thread()); thread->init_regs_kernel(); @@ -335,6 +346,7 @@ void kernel_wait(pid_t pid) [[noreturn]] void kernel_exit() { g_current->state = ThreadState::Dying; + Scheduler::signal_reap_thread(); kernel_yield(); unreachable(); } diff --git a/kernel/src/thread/Scheduler.h b/kernel/src/thread/Scheduler.h index 2688c3be..5dbc19cc 100644 --- a/kernel/src/thread/Scheduler.h +++ b/kernel/src/thread/Scheduler.h @@ -10,9 +10,12 @@ namespace Scheduler Thread* idle(); Thread* init_thread(); - Result new_kernel_thread(u64 address, const char* name); - Result new_kernel_thread(void (*func)(void), const char* name); - Result new_kernel_thread(void (*func)(void*), void* arg, const char* name); + void set_reap_thread(Thread*); + void signal_reap_thread(); + + Result new_kernel_thread(u64 address, const char* name); + Result new_kernel_thread(void (*func)(void), const char* name); + Result new_kernel_thread(void (*func)(void*), void* arg, const char* name); Result new_userspace_thread(SharedPtr inode, const char* name);