Skip to content

Commit 140a664

Browse files
committed
Kernel: Port FinalizerTask to WaitQueue
1 parent b341132 commit 140a664

File tree

4 files changed

+27
-16
lines changed

4 files changed

+27
-16
lines changed

Kernel/Tasks/FinalizerTask.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <Kernel/Tasks/FinalizerTask.h>
99
#include <Kernel/Tasks/Process.h>
1010
#include <Kernel/Tasks/Scheduler.h>
11+
#include <Kernel/Tasks/WaitQueue.h>
1112

1213
namespace Kernel {
1314

@@ -17,12 +18,13 @@ static void finalizer_task(void*)
1718
{
1819
Thread::current()->set_priority(THREAD_PRIORITY_LOW);
1920
while (!Process::current().is_dying()) {
20-
// The order of this if-else is important: We want to continue trying to finalize the threads in case
21-
// Thread::finalize_dying_threads set g_finalizer_has_work back to true due to OOM conditions
22-
if (g_finalizer_has_work.exchange(false, AK::MemoryOrder::memory_order_acq_rel) == true)
23-
Thread::finalize_dying_threads();
24-
else
25-
g_finalizer_wait_queue->wait_forever(finalizer_task_name);
21+
MUST(g_finalizer_wait_queue->wait_until(g_finalizer_has_work, [](bool& has_work) -> bool {
22+
if (!has_work)
23+
return false;
24+
has_work = false;
25+
return true;
26+
}));;
27+
Thread::finalize_dying_threads();
2628
}
2729
Process::current().sys$exit(0);
2830
VERIFY_NOT_REACHED();

Kernel/Tasks/Scheduler.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <Kernel/Tasks/PerformanceManager.h>
1717
#include <Kernel/Tasks/Process.h>
1818
#include <Kernel/Tasks/Scheduler.h>
19+
#include <Kernel/Tasks/WaitQueue.h>
1920
#include <Kernel/Time/TimeManagement.h>
2021
#include <Kernel/kstdio.h>
2122

@@ -32,8 +33,8 @@ static u32 time_slice_for(Thread const& thread)
3233
}
3334

3435
READONLY_AFTER_INIT Thread* g_finalizer;
35-
READONLY_AFTER_INIT DeprecatedWaitQueue* g_finalizer_wait_queue;
36-
Atomic<bool> g_finalizer_has_work { false };
36+
READONLY_AFTER_INIT WaitQueue* g_finalizer_wait_queue;
37+
SpinlockProtected<bool, LockRank::None> g_finalizer_has_work;
3738
READONLY_AFTER_INIT static Process* s_colonel_process;
3839

3940
struct ThreadReadyQueue {
@@ -376,9 +377,11 @@ UNMAP_AFTER_INIT void Scheduler::initialize()
376377
VERIFY(Processor::is_initialized()); // sanity check
377378
VERIFY(TimeManagement::is_initialized());
378379

379-
g_finalizer_wait_queue = new DeprecatedWaitQueue;
380+
g_finalizer_wait_queue = new WaitQueue;
380381

381-
g_finalizer_has_work.store(false, AK::MemoryOrder::memory_order_release);
382+
g_finalizer_has_work.with([](auto& has_work) {
383+
has_work = false;
384+
});
382385
auto [colonel_process, idle_thread] = MUST(Process::create_kernel_process("colonel"sv, idle_loop, nullptr, 1, Process::RegisterProcess::No));
383386
s_colonel_process = &colonel_process.leak_ref();
384387
idle_thread->set_priority(THREAD_PRIORITY_MIN);
@@ -477,8 +480,10 @@ void Scheduler::invoke_async()
477480

478481
void Scheduler::notify_finalizer()
479482
{
480-
if (!g_finalizer_has_work.exchange(true, AK::MemoryOrder::memory_order_acq_rel))
481-
g_finalizer_wait_queue->wake_all();
483+
g_finalizer_has_work.with([](auto& has_work) {
484+
has_work = true;
485+
g_finalizer_wait_queue->notify_all();
486+
});
482487
}
483488

484489
void Scheduler::idle_loop(void*)

Kernel/Tasks/Scheduler.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <AK/Types.h>
1313
#include <Kernel/Forward.h>
1414
#include <Kernel/Locking/Spinlock.h>
15+
#include <Kernel/Locking/SpinlockProtected.h>
1516
#include <Kernel/Time/TimeManagement.h>
1617
#include <Kernel/UnixTypes.h>
1718

@@ -20,8 +21,8 @@ namespace Kernel {
2021
struct RegisterState;
2122

2223
extern Thread* g_finalizer;
23-
extern DeprecatedWaitQueue* g_finalizer_wait_queue;
24-
extern Atomic<bool> g_finalizer_has_work;
24+
extern WaitQueue* g_finalizer_wait_queue;
25+
extern SpinlockProtected<bool, LockRank::None> g_finalizer_has_work;
2526
extern RecursiveSpinlock<LockRank::None> g_scheduler_lock;
2627

2728
struct TotalTimeScheduled {

Kernel/Tasks/Thread.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -577,8 +577,11 @@ void Thread::finalize_dying_threads()
577577
auto result = dying_threads.try_append(&thread);
578578
// We ignore allocation failures above the first 32 guaranteed thread slots, and
579579
// just flag our future-selves to finalize these threads at a later point
580-
if (result.is_error())
581-
g_finalizer_has_work.store(true, AK::MemoryOrder::memory_order_release);
580+
if (result.is_error()) {
581+
g_finalizer_has_work.with([](bool& has_work) {
582+
has_work = true;
583+
});
584+
}
582585
});
583586
}
584587
for (auto* thread : dying_threads) {

0 commit comments

Comments
 (0)