| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- // 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
|