From 643e87a076bfb1b3e5fd65d2d79ff38f80e96bc2 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Thu, 3 Aug 2023 10:42:14 +0300 Subject: [PATCH] Kernel: Threads are deleted sooner and cleaner We now delete threads when 1. it is marked as Terminated and is the current thread 2. it tries to start execution in Terminated state This allows us to never have thread executing in Terminated state --- kernel/arch/x86_64/IDT.cpp | 14 +++++--------- kernel/kernel/Syscall.cpp | 6 +----- kernel/kernel/Thread.cpp | 28 +++++++++++++++++++++++----- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/kernel/arch/x86_64/IDT.cpp b/kernel/arch/x86_64/IDT.cpp index 028fda268..0c2754390 100644 --- a/kernel/arch/x86_64/IDT.cpp +++ b/kernel/arch/x86_64/IDT.cpp @@ -201,13 +201,11 @@ namespace IDT Kernel::panic("Unhandled exception"); } - // Don't continue exection when terminated - if (Kernel::Thread::current().state() == Kernel::Thread::State::Terminated) - Kernel::Scheduler::get().execute_current_thread(); - + ASSERT(Kernel::Thread::current().state() != Kernel::Thread::State::Terminated); + if (from_userspace) { - ASSERT(Kernel::Thread::current().state() != Kernel::Thread::State::Terminating); + ASSERT(Kernel::Thread::current().state() == Kernel::Thread::State::Executing); Kernel::Thread::current().load_sse(); } } @@ -243,13 +241,11 @@ namespace IDT Kernel::Scheduler::get().reschedule_if_idling(); - // Don't continue exection when terminated - if (Kernel::Thread::current().state() == Kernel::Thread::State::Terminated) - Kernel::Scheduler::get().execute_current_thread(); + ASSERT(Kernel::Thread::current().state() != Kernel::Thread::State::Terminated); if (from_userspace) { - ASSERT(Kernel::Thread::current().state() != Kernel::Thread::State::Terminating); + ASSERT(Kernel::Thread::current().state() == Kernel::Thread::State::Executing); Kernel::Thread::current().load_sse(); } } diff --git a/kernel/kernel/Syscall.cpp b/kernel/kernel/Syscall.cpp index 55406e5d4..de6137aa5 100644 --- a/kernel/kernel/Syscall.cpp +++ b/kernel/kernel/Syscall.cpp @@ -177,11 +177,7 @@ namespace Kernel asm volatile("cli"); - // Don't continue exection when terminated - if (Kernel::Thread::current().state() == Kernel::Thread::State::Terminated) - Kernel::Scheduler::get().execute_current_thread(); - - ASSERT(Kernel::Thread::current().state() != Kernel::Thread::State::Terminating); + ASSERT(Kernel::Thread::current().state() == Kernel::Thread::State::Executing); Thread::current().load_sse(); if (ret.is_error()) diff --git a/kernel/kernel/Thread.cpp b/kernel/kernel/Thread.cpp index 800c11349..d59b3fd2a 100644 --- a/kernel/kernel/Thread.cpp +++ b/kernel/kernel/Thread.cpp @@ -31,6 +31,9 @@ namespace Kernel { CriticalScope _; + // FIXME: this should not be a requirement + ASSERT(&thread == &Thread::current()); + if (m_thread.state() == State::Executing || m_thread.m_terminate_blockers > 0) { m_thread.m_terminate_blockers++; @@ -38,8 +41,11 @@ namespace Kernel } if (m_thread.state() == State::Terminating && m_thread.m_terminate_blockers == 0) + { m_thread.m_state = State::Terminated; - + Scheduler::get().execute_current_thread(); + } + while (true) Scheduler::get().reschedule(); } @@ -54,17 +60,29 @@ namespace Kernel return; if (m_thread.state() == State::Terminating && m_thread.m_terminate_blockers == 0) + { m_thread.m_state = State::Terminated; + Scheduler::get().execute_current_thread(); + } - while (true) - Scheduler::get().reschedule(); + ASSERT_NOT_REACHED(); } void Thread::set_terminating() { CriticalScope _; - m_state = m_terminate_blockers == 0 ? State::Terminated : State::Terminating; - Scheduler::get().unblock_thread(tid()); + if (m_terminate_blockers == 0) + { + m_state = State::Terminated; + if (this == &Thread::current()) + Scheduler::get().execute_current_thread(); + } + else + { + m_state = State::Terminating; + if (this == &Thread::current()) + Scheduler::get().unblock_thread(tid()); + } } static pid_t s_next_tid = 1;