From f4978b2be1dc37559754964a9eb99022a02a634b Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 22 Dec 2019 12:23:44 +0100 Subject: [PATCH] Kernel: Use IntrusiveList to make WaitQueue allocation-free :^) --- Kernel/Thread.cpp | 22 ++++++++++++++++++++++ Kernel/Thread.h | 26 ++++---------------------- Kernel/WaitQueue.cpp | 2 +- Kernel/WaitQueue.h | 6 +++--- 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index c3d62b13c7..63abbeb310 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -776,3 +776,25 @@ const char* to_string(ThreadPriority priority) ASSERT_NOT_REACHED(); return nullptr; } + +void Thread::wait_on(WaitQueue& queue, Thread* beneficiary, const char* reason) +{ + bool did_unlock = unlock_process_if_locked(); + cli(); + set_state(State::Queued); + queue.enqueue(*current); + // Yield and wait for the queue to wake us up again. + if (beneficiary) + Scheduler::donate_to(beneficiary, reason); + else + Scheduler::yield(); + // We've unblocked, relock the process if needed and carry on. + if (did_unlock) + relock_process(); +} + +void Thread::wake_from_queue() +{ + ASSERT(state() == State::Queued); + set_state(State::Runnable); +} diff --git a/Kernel/Thread.h b/Kernel/Thread.h index 796dbacaf3..a12178ec6f 100644 --- a/Kernel/Thread.h +++ b/Kernel/Thread.h @@ -11,7 +11,6 @@ #include #include #include -#include #include class Alarm; @@ -291,27 +290,8 @@ public: return block(state_string, move(condition)); } - void wait_on(WaitQueue& queue, Thread* beneficiary = nullptr, const char* reason = nullptr) - { - bool did_unlock = unlock_process_if_locked(); - cli(); - set_state(State::Queued); - queue.enqueue(*current); - // Yield and wait for the queue to wake us up again. - if (beneficiary) - Scheduler::donate_to(beneficiary, reason); - else - Scheduler::yield(); - // We've unblocked, relock the process if needed and carry on. - if (did_unlock) - relock_process(); - } - - void wake_from_queue() - { - ASSERT(state() == State::Queued); - set_state(State::Runnable); - } + void wait_on(WaitQueue& queue, Thread* beneficiary = nullptr, const char* reason = nullptr); + void wake_from_queue(); void unblock(); @@ -423,9 +403,11 @@ public: private: IntrusiveListNode m_runnable_list_node; + IntrusiveListNode m_wait_queue_node; private: friend class SchedulerData; + friend class WaitQueue; bool unlock_process_if_locked(); void relock_process(); diff --git a/Kernel/WaitQueue.cpp b/Kernel/WaitQueue.cpp index 8531b57cdb..e3541e93f3 100644 --- a/Kernel/WaitQueue.cpp +++ b/Kernel/WaitQueue.cpp @@ -12,7 +12,7 @@ WaitQueue::~WaitQueue() void WaitQueue::enqueue(Thread& thread) { InterruptDisabler disabler; - m_threads.append(&thread); + m_threads.append(thread); } void WaitQueue::wake_one() diff --git a/Kernel/WaitQueue.h b/Kernel/WaitQueue.h index 0d4a820cab..ebe46702bf 100644 --- a/Kernel/WaitQueue.h +++ b/Kernel/WaitQueue.h @@ -1,8 +1,7 @@ #pragma once #include - -class Thread; +#include class WaitQueue { public: @@ -14,5 +13,6 @@ public: void wake_all(); private: - SinglyLinkedList m_threads; + typedef IntrusiveList ThreadList; + ThreadList m_threads; };