kernel: Tell the reap thread to run when it's needed, instead of checking every 200 ms

This commit is contained in:
apio 2023-05-04 23:06:00 +02:00
parent 42eb0a1d74
commit 96f3d29d37
Signed by: apio
GPG Key ID: B8A7D06E42258954
4 changed files with 27 additions and 10 deletions

View File

@ -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<void> 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) {

View File

@ -51,6 +51,7 @@ Result<u64> 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);

View File

@ -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<void> 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<Thread*> 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<void> new_kernel_thread(u64 address, const char* name)
Result<Thread*> 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<void> new_kernel_thread(void (*func)(void), const char* name)
Result<Thread*> 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<void> new_kernel_thread(void (*func)(void*), void* arg, const char* name)
Result<Thread*> 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();
}

View File

@ -10,9 +10,12 @@ namespace Scheduler
Thread* idle();
Thread* init_thread();
Result<void> new_kernel_thread(u64 address, const char* name);
Result<void> new_kernel_thread(void (*func)(void), const char* name);
Result<void> new_kernel_thread(void (*func)(void*), void* arg, const char* name);
void set_reap_thread(Thread*);
void signal_reap_thread();
Result<Thread*> new_kernel_thread(u64 address, const char* name);
Result<Thread*> new_kernel_thread(void (*func)(void), const char* name);
Result<Thread*> new_kernel_thread(void (*func)(void*), void* arg, const char* name);
Result<Thread*> new_userspace_thread(SharedPtr<VFS::Inode> inode, const char* name);