From e57c1fc9fce5f569a9b8820eabef5a5eee549ba4 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 028fda26..0c275439 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 55406e5d..de6137aa 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 800c1134..d59b3fd2 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;