core: hle: kernel: Add KWorkerTask and KWorkerTaskManager.

- These primitives are used to dispatch asynchronous kernel tasks from KThread and KProcess.
This commit is contained in:
bunnei 2022-01-14 16:24:59 -08:00
parent f6de57c1a5
commit bf32fcc817
4 changed files with 96 additions and 0 deletions

View File

@ -247,6 +247,9 @@ add_library(core STATIC
hle/kernel/k_trace.h
hle/kernel/k_transfer_memory.cpp
hle/kernel/k_transfer_memory.h
hle/kernel/k_worker_task.h
hle/kernel/k_worker_task_manager.cpp
hle/kernel/k_worker_task_manager.h
hle/kernel/k_writable_event.cpp
hle/kernel/k_writable_event.h
hle/kernel/kernel.cpp

View File

@ -0,0 +1,18 @@
// Copyright 2022 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/kernel/k_synchronization_object.h"
namespace Kernel {
class KWorkerTask : public KSynchronizationObject {
public:
explicit KWorkerTask(KernelCore& kernel_);
void DoWorkerTask();
};
} // namespace Kernel

View File

@ -0,0 +1,42 @@
// Copyright 2022 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/assert.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/k_worker_task.h"
#include "core/hle/kernel/k_worker_task_manager.h"
#include "core/hle/kernel/kernel.h"
namespace Kernel {
KWorkerTask::KWorkerTask(KernelCore& kernel_) : KSynchronizationObject{kernel_} {}
void KWorkerTask::DoWorkerTask() {
if (auto* const thread = this->DynamicCast<KThread*>(); thread != nullptr) {
return thread->DoWorkerTaskImpl();
} else {
auto* const process = this->DynamicCast<KProcess*>();
ASSERT(process != nullptr);
return process->DoWorkerTaskImpl();
}
}
KWorkerTaskManager::KWorkerTaskManager() : m_waiting_thread(1, "yuzu:KWorkerTaskManager") {}
void KWorkerTaskManager::AddTask(KernelCore& kernel, WorkerType type, KWorkerTask* task) {
ASSERT(type <= WorkerType::Count);
kernel.WorkerTaskManager().AddTask(kernel, task);
}
void KWorkerTaskManager::AddTask(KernelCore& kernel, KWorkerTask* task) {
KScopedSchedulerLock sl(kernel);
m_waiting_thread.QueueWork([task]() {
// Do the task.
task->DoWorkerTask();
});
}
} // namespace Kernel

View File

@ -0,0 +1,33 @@
// Copyright 2022 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "common/common_types.h"
#include "common/thread_worker.h"
namespace Kernel {
class KernelCore;
class KWorkerTask;
class KWorkerTaskManager final {
public:
enum class WorkerType : u32 {
Exit,
Count,
};
KWorkerTaskManager();
static void AddTask(KernelCore& kernel_, WorkerType type, KWorkerTask* task);
private:
void AddTask(KernelCore& kernel, KWorkerTask* task);
private:
Common::ThreadWorker m_waiting_thread;
};
} // namespace Kernel