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 028fda2689..0c27543907 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 55406e5d48..de6137aa55 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 800c113494..d59b3fd2a9 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;