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;