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 a11b5ae41f
commit e57c1fc9fc
3 changed files with 29 additions and 19 deletions

View File

@ -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();
}
}

View File

@ -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())

View File

@ -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;