summaryrefslogtreecommitdiff
path: root/Kernel/Thread.cpp
diff options
context:
space:
mode:
authorRobin Burchell <robin+git@viroteck.net>2019-07-19 13:04:42 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-07-19 15:42:30 +0200
commit53262cd08b08f3d4d2b77cff9c348e84b1bf5eb9 (patch)
treed152a2fb95acbc0e49b2387dcb845a06c89694f6 /Kernel/Thread.cpp
parent218069f421cb7b228320ce31aa78dc72ae59e9c1 (diff)
downloadserenity-53262cd08b08f3d4d2b77cff9c348e84b1bf5eb9.zip
AK: Introduce IntrusiveList
And use it in the scheduler. IntrusiveList is similar to InlineLinkedList, except that rather than making assertions about the type (and requiring inheritance), it provides an IntrusiveListNode type that can be used to put an instance into many different lists at once. As a proof of concept, port the scheduler over to use it. The only downside here is that the "list" global needs to know the position of the IntrusiveListNode member, so we have to position things a little awkwardly to make that happen. We also move the runnable lists to Thread, to avoid having to publicize the node.
Diffstat (limited to 'Kernel/Thread.cpp')
-rw-r--r--Kernel/Thread.cpp39
1 files changed, 17 insertions, 22 deletions
diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp
index fafdac3536..c82e54a042 100644
--- a/Kernel/Thread.cpp
+++ b/Kernel/Thread.cpp
@@ -16,8 +16,8 @@ HashTable<Thread*>& thread_table()
return *table;
}
-InlineLinkedList<Thread>* g_runnable_threads;
-InlineLinkedList<Thread>* g_nonrunnable_threads;
+Thread::SchedulerThreadList* Thread::g_runnable_threads;
+Thread::SchedulerThreadList* Thread::g_nonrunnable_threads;
static const u32 default_kernel_stack_size = 65536;
static const u32 default_userspace_stack_size = 65536;
@@ -75,7 +75,7 @@ Thread::Thread(Process& process)
if (m_process.pid() != 0) {
InterruptDisabler disabler;
thread_table().set(this);
- set_thread_list(g_nonrunnable_threads);
+ g_nonrunnable_threads->append(*this);
}
}
@@ -85,8 +85,6 @@ Thread::~Thread()
kfree_aligned(m_fpu_state);
{
InterruptDisabler disabler;
- if (m_thread_list)
- m_thread_list->remove(this);
thread_table().remove(this);
}
@@ -534,8 +532,8 @@ KResult Thread::wait_for_connect(FileDescription& description)
void Thread::initialize()
{
- g_runnable_threads = new InlineLinkedList<Thread>;
- g_nonrunnable_threads = new InlineLinkedList<Thread>;
+ g_runnable_threads = new SchedulerThreadList;
+ g_nonrunnable_threads = new SchedulerThreadList;
Scheduler::initialize();
}
@@ -555,23 +553,20 @@ bool Thread::is_thread(void* ptr)
return thread_table().contains((Thread*)ptr);
}
-void Thread::set_thread_list(InlineLinkedList<Thread>* thread_list)
-{
- ASSERT_INTERRUPTS_DISABLED();
- ASSERT(pid() != 0);
- if (m_thread_list == thread_list)
- return;
- if (m_thread_list)
- m_thread_list->remove(this);
- if (thread_list)
- thread_list->append(this);
- m_thread_list = thread_list;
-}
-
void Thread::set_state(State new_state)
{
InterruptDisabler disabler;
m_state = new_state;
- if (m_process.pid() != 0)
- set_thread_list(thread_list_for_state(new_state));
+ if (m_process.pid() != 0) {
+ SchedulerThreadList* list = nullptr;
+ if (is_runnable_state(new_state))
+ list = g_runnable_threads;
+ else
+ list = g_nonrunnable_threads;
+
+ if (list->contains(*this))
+ return;
+
+ list->append(*this);
+ }
}