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
This commit is contained in:
Bananymous 2023-08-03 10:42:14 +03:00
parent 20eafb4cc4
commit 643e87a076
3 changed files with 29 additions and 19 deletions

View File

@ -201,13 +201,11 @@ namespace IDT
Kernel::panic("Unhandled exception"); Kernel::panic("Unhandled exception");
} }
// Don't continue exection when terminated ASSERT(Kernel::Thread::current().state() != Kernel::Thread::State::Terminated);
if (Kernel::Thread::current().state() == Kernel::Thread::State::Terminated)
Kernel::Scheduler::get().execute_current_thread();
if (from_userspace) 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(); Kernel::Thread::current().load_sse();
} }
} }
@ -243,13 +241,11 @@ namespace IDT
Kernel::Scheduler::get().reschedule_if_idling(); Kernel::Scheduler::get().reschedule_if_idling();
// Don't continue exection when terminated ASSERT(Kernel::Thread::current().state() != Kernel::Thread::State::Terminated);
if (Kernel::Thread::current().state() == Kernel::Thread::State::Terminated)
Kernel::Scheduler::get().execute_current_thread();
if (from_userspace) 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(); Kernel::Thread::current().load_sse();
} }
} }

View File

@ -177,11 +177,7 @@ namespace Kernel
asm volatile("cli"); asm volatile("cli");
// Don't continue exection when terminated ASSERT(Kernel::Thread::current().state() == Kernel::Thread::State::Executing);
if (Kernel::Thread::current().state() == Kernel::Thread::State::Terminated)
Kernel::Scheduler::get().execute_current_thread();
ASSERT(Kernel::Thread::current().state() != Kernel::Thread::State::Terminating);
Thread::current().load_sse(); Thread::current().load_sse();
if (ret.is_error()) if (ret.is_error())

View File

@ -31,6 +31,9 @@ namespace Kernel
{ {
CriticalScope _; CriticalScope _;
// FIXME: this should not be a requirement
ASSERT(&thread == &Thread::current());
if (m_thread.state() == State::Executing || m_thread.m_terminate_blockers > 0) if (m_thread.state() == State::Executing || m_thread.m_terminate_blockers > 0)
{ {
m_thread.m_terminate_blockers++; m_thread.m_terminate_blockers++;
@ -38,8 +41,11 @@ namespace Kernel
} }
if (m_thread.state() == State::Terminating && m_thread.m_terminate_blockers == 0) if (m_thread.state() == State::Terminating && m_thread.m_terminate_blockers == 0)
{
m_thread.m_state = State::Terminated; m_thread.m_state = State::Terminated;
Scheduler::get().execute_current_thread();
}
while (true) while (true)
Scheduler::get().reschedule(); Scheduler::get().reschedule();
} }
@ -54,17 +60,29 @@ namespace Kernel
return; return;
if (m_thread.state() == State::Terminating && m_thread.m_terminate_blockers == 0) if (m_thread.state() == State::Terminating && m_thread.m_terminate_blockers == 0)
{
m_thread.m_state = State::Terminated; m_thread.m_state = State::Terminated;
Scheduler::get().execute_current_thread();
}
while (true) ASSERT_NOT_REACHED();
Scheduler::get().reschedule();
} }
void Thread::set_terminating() void Thread::set_terminating()
{ {
CriticalScope _; CriticalScope _;
m_state = m_terminate_blockers == 0 ? State::Terminated : State::Terminating; if (m_terminate_blockers == 0)
Scheduler::get().unblock_thread(tid()); {
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; static pid_t s_next_tid = 1;