Răsfoiți Sursa

core: hle: kernel: Add KWorkerTask and KWorkerTaskManager.

- These primitives are used to dispatch asynchronous kernel tasks from KThread and KProcess.
bunnei 4 ani în urmă
părinte
comite
bf32fcc817

+ 3 - 0
src/core/CMakeLists.txt

@@ -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

+ 18 - 0
src/core/hle/kernel/k_worker_task.h

@@ -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

+ 42 - 0
src/core/hle/kernel/k_worker_task_manager.cpp

@@ -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

+ 33 - 0
src/core/hle/kernel/k_worker_task_manager.h

@@ -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