summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel/k_thread_queue.h
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2021-01-30 08:06:40 +0100
committerGitHub <noreply@github.com>2021-01-30 08:06:40 +0100
commita4526c4e1acb50808bbe205952101142288e1c60 (patch)
tree7109edf89606c43352da9de40d0e3a920a08b659 /src/core/hle/kernel/k_thread_queue.h
parentMerge pull request #5795 from ReinUsesLisp/bytes-to-map-end (diff)
parenthle: kernel: KLightLock: Fix several bugs. (diff)
downloadyuzu-a4526c4e1acb50808bbe205952101142288e1c60.tar
yuzu-a4526c4e1acb50808bbe205952101142288e1c60.tar.gz
yuzu-a4526c4e1acb50808bbe205952101142288e1c60.tar.bz2
yuzu-a4526c4e1acb50808bbe205952101142288e1c60.tar.lz
yuzu-a4526c4e1acb50808bbe205952101142288e1c60.tar.xz
yuzu-a4526c4e1acb50808bbe205952101142288e1c60.tar.zst
yuzu-a4526c4e1acb50808bbe205952101142288e1c60.zip
Diffstat (limited to '')
-rw-r--r--src/core/hle/kernel/k_thread_queue.h81
1 files changed, 81 insertions, 0 deletions
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 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/kernel/k_thread.h"
+
+namespace Kernel {
+
+class KThreadQueue {
+public:
+ explicit KThreadQueue(KernelCore& kernel) : kernel{kernel} {}
+
+ bool IsEmpty() const {
+ return wait_list.empty();
+ }
+
+ KThread::WaiterList::iterator begin() {
+ return wait_list.begin();
+ }
+ KThread::WaiterList::iterator end() {
+ return wait_list.end();
+ }
+
+ bool SleepThread(KThread* t) {
+ KScopedSchedulerLock sl{kernel};
+
+ // If the thread needs terminating, don't enqueue it.
+ if (t->IsTerminationRequested()) {
+ return false;
+ }
+
+ // Set the thread's queue and mark it as waiting.
+ t->SetSleepingQueue(this);
+ t->SetState(ThreadState::Waiting);
+
+ // Add the thread to the queue.
+ wait_list.push_back(*t);
+
+ return true;
+ }
+
+ void WakeupThread(KThread* t) {
+ KScopedSchedulerLock sl{kernel};
+
+ // Remove the thread from the queue.
+ wait_list.erase(wait_list.iterator_to(*t));
+
+ // Mark the thread as no longer sleeping.
+ t->SetState(ThreadState::Runnable);
+ t->SetSleepingQueue(nullptr);
+ }
+
+ KThread* WakeupFrontThread() {
+ KScopedSchedulerLock sl{kernel};
+
+ if (wait_list.empty()) {
+ return nullptr;
+ } else {
+ // Remove the thread from the queue.
+ auto it = wait_list.begin();
+ KThread* thread = std::addressof(*it);
+ wait_list.erase(it);
+
+ ASSERT(thread->GetState() == ThreadState::Waiting);
+
+ // Mark the thread as no longer sleeping.
+ thread->SetState(ThreadState::Runnable);
+ thread->SetSleepingQueue(nullptr);
+
+ return thread;
+ }
+ }
+
+private:
+ KernelCore& kernel;
+ KThread::WaiterList wait_list{};
+};
+
+} // namespace Kernel