mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 18:07:35 +00:00
Kernel: Use IntrusiveList to make WaitQueue allocation-free :^)
This commit is contained in:
parent
96cfddb3ac
commit
f4978b2be1
4 changed files with 30 additions and 26 deletions
|
@ -776,3 +776,25 @@ const char* to_string(ThreadPriority priority)
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
return nullptr;
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#include <Kernel/Scheduler.h>
|
#include <Kernel/Scheduler.h>
|
||||||
#include <Kernel/UnixTypes.h>
|
#include <Kernel/UnixTypes.h>
|
||||||
#include <Kernel/VM/Region.h>
|
#include <Kernel/VM/Region.h>
|
||||||
#include <Kernel/WaitQueue.h>
|
|
||||||
#include <LibC/fd_set.h>
|
#include <LibC/fd_set.h>
|
||||||
|
|
||||||
class Alarm;
|
class Alarm;
|
||||||
|
@ -291,27 +290,8 @@ public:
|
||||||
return block<ConditionBlocker>(state_string, move(condition));
|
return block<ConditionBlocker>(state_string, move(condition));
|
||||||
}
|
}
|
||||||
|
|
||||||
void wait_on(WaitQueue& queue, Thread* beneficiary = nullptr, const char* reason = nullptr)
|
void wait_on(WaitQueue& queue, Thread* beneficiary = nullptr, const char* reason = nullptr);
|
||||||
{
|
void wake_from_queue();
|
||||||
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 unblock();
|
void unblock();
|
||||||
|
|
||||||
|
@ -423,9 +403,11 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IntrusiveListNode m_runnable_list_node;
|
IntrusiveListNode m_runnable_list_node;
|
||||||
|
IntrusiveListNode m_wait_queue_node;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class SchedulerData;
|
friend class SchedulerData;
|
||||||
|
friend class WaitQueue;
|
||||||
bool unlock_process_if_locked();
|
bool unlock_process_if_locked();
|
||||||
void relock_process();
|
void relock_process();
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ WaitQueue::~WaitQueue()
|
||||||
void WaitQueue::enqueue(Thread& thread)
|
void WaitQueue::enqueue(Thread& thread)
|
||||||
{
|
{
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
m_threads.append(&thread);
|
m_threads.append(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaitQueue::wake_one()
|
void WaitQueue::wake_one()
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/SinglyLinkedList.h>
|
#include <AK/SinglyLinkedList.h>
|
||||||
|
#include <Kernel/Thread.h>
|
||||||
class Thread;
|
|
||||||
|
|
||||||
class WaitQueue {
|
class WaitQueue {
|
||||||
public:
|
public:
|
||||||
|
@ -14,5 +13,6 @@ public:
|
||||||
void wake_all();
|
void wake_all();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SinglyLinkedList<Thread*> m_threads;
|
typedef IntrusiveList<Thread, &Thread::m_wait_queue_node> ThreadList;
|
||||||
|
ThreadList m_threads;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue