mirror of
https://github.com/yuzu-mirror/yuzu.git
synced 2024-11-06 03:29:59 +00:00
core: hle: kernel: Implement KThreadQueue.
This commit is contained in:
parent
2fb77adb9f
commit
97129bc742
2 changed files with 82 additions and 0 deletions
|
@ -170,6 +170,7 @@ add_library(core STATIC
|
||||||
hle/kernel/k_synchronization_object.h
|
hle/kernel/k_synchronization_object.h
|
||||||
hle/kernel/k_thread.cpp
|
hle/kernel/k_thread.cpp
|
||||||
hle/kernel/k_thread.h
|
hle/kernel/k_thread.h
|
||||||
|
hle/kernel/k_thread_queue.h
|
||||||
hle/kernel/kernel.cpp
|
hle/kernel/kernel.cpp
|
||||||
hle/kernel/kernel.h
|
hle/kernel/kernel.h
|
||||||
hle/kernel/memory/address_space_info.cpp
|
hle/kernel/memory/address_space_info.cpp
|
||||||
|
|
81
src/core/hle/kernel/k_thread_queue.h
Normal file
81
src/core/hle/kernel/k_thread_queue.h
Normal file
|
@ -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
|
Loading…
Reference in a new issue