summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar bunnei2021-01-15 21:53:56 -0800
committerGravatar bunnei2021-01-28 21:42:25 -0800
commit97129bc742cd8972c87c9f087914729419d5b6c8 (patch)
treeb117512bc49a429a64659f54f129041963fef5ea /src/core
parentcommon: common_funcs: Add a few more useful macros for kernel code. (diff)
downloadyuzu-97129bc742cd8972c87c9f087914729419d5b6c8.tar.gz
yuzu-97129bc742cd8972c87c9f087914729419d5b6c8.tar.xz
yuzu-97129bc742cd8972c87c9f087914729419d5b6c8.zip
core: hle: kernel: Implement KThreadQueue.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/hle/kernel/k_thread_queue.h81
2 files changed, 82 insertions, 0 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 88a31e0f2..843bce150 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -170,6 +170,7 @@ add_library(core STATIC
170 hle/kernel/k_synchronization_object.h 170 hle/kernel/k_synchronization_object.h
171 hle/kernel/k_thread.cpp 171 hle/kernel/k_thread.cpp
172 hle/kernel/k_thread.h 172 hle/kernel/k_thread.h
173 hle/kernel/k_thread_queue.h
173 hle/kernel/kernel.cpp 174 hle/kernel/kernel.cpp
174 hle/kernel/kernel.h 175 hle/kernel/kernel.h
175 hle/kernel/memory/address_space_info.cpp 176 hle/kernel/memory/address_space_info.cpp
diff --git a/src/core/hle/kernel/k_thread_queue.h b/src/core/hle/kernel/k_thread_queue.h
new file mode 100644
index 000000000..c52eba249
--- /dev/null
+++ b/src/core/hle/kernel/k_thread_queue.h
@@ -0,0 +1,81 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/kernel/k_thread.h"
8
9namespace Kernel {
10
11class KThreadQueue {
12public:
13 explicit KThreadQueue(KernelCore& kernel) : kernel{kernel} {}
14
15 bool IsEmpty() const {
16 return wait_list.empty();
17 }
18
19 KThread::WaiterList::iterator begin() {
20 return wait_list.begin();
21 }
22 KThread::WaiterList::iterator end() {
23 return wait_list.end();
24 }
25
26 bool SleepThread(KThread* t) {
27 KScopedSchedulerLock sl{kernel};
28
29 // If the thread needs terminating, don't enqueue it.
30 if (t->IsTerminationRequested()) {
31 return false;
32 }
33
34 // Set the thread's queue and mark it as waiting.
35 t->SetSleepingQueue(this);
36 t->SetState(ThreadState::Waiting);
37
38 // Add the thread to the queue.
39 wait_list.push_back(*t);
40
41 return true;
42 }
43
44 void WakeupThread(KThread* t) {
45 KScopedSchedulerLock sl{kernel};
46
47 // Remove the thread from the queue.
48 wait_list.erase(wait_list.iterator_to(*t));
49
50 // Mark the thread as no longer sleeping.
51 t->SetState(ThreadState::Runnable);
52 t->SetSleepingQueue(nullptr);
53 }
54
55 KThread* WakeupFrontThread() {
56 KScopedSchedulerLock sl{kernel};
57
58 if (wait_list.empty()) {
59 return nullptr;
60 } else {
61 // Remove the thread from the queue.
62 auto it = wait_list.begin();
63 KThread* thread = std::addressof(*it);
64 wait_list.erase(it);
65
66 ASSERT(thread->GetState() == ThreadState::Waiting);
67
68 // Mark the thread as no longer sleeping.
69 thread->SetState(ThreadState::Runnable);
70 thread->SetSleepingQueue(nullptr);
71
72 return thread;
73 }
74 }
75
76private:
77 KernelCore& kernel;
78 KThread::WaiterList wait_list{};
79};
80
81} // namespace Kernel