Kernel: Ignore allocation failures during thread finalization

We ignore allocation failures above the first 32 guaranteed thread
slots, and just flag our future-selves to finalize these threads at a
later point.
This commit is contained in:
Idan Horowitz 2022-01-26 18:34:31 +02:00 committed by Linus Groh
parent 7e9df6ddba
commit a0f404551e
Notes: sideshowbarker 2024-07-17 20:10:27 +09:00
2 changed files with 11 additions and 4 deletions

View file

@ -14,10 +14,12 @@ static void finalizer_task(void*)
{ {
Thread::current()->set_priority(THREAD_PRIORITY_LOW); Thread::current()->set_priority(THREAD_PRIORITY_LOW);
for (;;) { for (;;) {
g_finalizer_wait_queue->wait_forever("FinalizerTask"); // The order of this if-else is important: We want to continue trying to finalize the threads in case
// Thread::finalize_dying_threads set g_finalizer_has_work back to true due to OOM conditions
if (g_finalizer_has_work.exchange(false, AK::MemoryOrder::memory_order_acq_rel) == true) if (g_finalizer_has_work.exchange(false, AK::MemoryOrder::memory_order_acq_rel) == true)
Thread::finalize_dying_threads(); Thread::finalize_dying_threads();
else
g_finalizer_wait_queue->wait_forever("FinalizerTask");
} }
}; };

View file

@ -529,8 +529,13 @@ void Thread::finalize_dying_threads()
{ {
SpinlockLocker lock(g_scheduler_lock); SpinlockLocker lock(g_scheduler_lock);
for_each_in_state(Thread::State::Dying, [&](Thread& thread) { for_each_in_state(Thread::State::Dying, [&](Thread& thread) {
if (thread.is_finalizable()) if (!thread.is_finalizable())
dying_threads.append(&thread); return;
auto result = dying_threads.try_append(&thread);
// We ignore allocation failures above the first 32 guaranteed thread slots, and
// just flag our future-selves to finalize these threads at a later point
if (result.is_error())
g_finalizer_has_work.store(true, AK::MemoryOrder::memory_order_release);
}); });
} }
for (auto* thread : dying_threads) { for (auto* thread : dying_threads) {