From dbf6cd511720c9f36f9735edf74fbf7a80676696 Mon Sep 17 00:00:00 2001 From: Maide <34639600+Kelebek1@users.noreply.github.com> Date: Wed, 9 Feb 2022 20:46:46 +0000 Subject: LowPrioThreadMgr (#82) --- src/KingSystem/Utils/Thread/LowPrioThreadMgr.cpp | 119 +++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/KingSystem/Utils/Thread/LowPrioThreadMgr.cpp (limited to 'src/KingSystem/Utils/Thread/LowPrioThreadMgr.cpp') diff --git a/src/KingSystem/Utils/Thread/LowPrioThreadMgr.cpp b/src/KingSystem/Utils/Thread/LowPrioThreadMgr.cpp new file mode 100644 index 00000000..35f69e48 --- /dev/null +++ b/src/KingSystem/Utils/Thread/LowPrioThreadMgr.cpp @@ -0,0 +1,119 @@ +#include "KingSystem/Utils/Thread/LowPrioThreadMgr.h" +#include +#include +#include +#include "KingSystem/Utils/SafeDelete.h" +#include "KingSystem/Utils/Thread/TaskQueue.h" + +namespace ksys::util { + +SEAD_SINGLETON_DISPOSER_IMPL(LowPrioThreadMgr) + +LowPrioThreadMgr::~LowPrioThreadMgr() { + const s32 num_tasks = mCoreThreadTasks.size(); + + for (s32 i = 0; i < num_tasks; i++) { + mCoreThreadTasks[i].task_thread->quitAndWaitDoneSingleThread(false); + util::safeDelete(mCoreThreadTasks[i].task_thread); + util::safeDelete(mCoreThreadTasks[i].task_mgr); + } + mCoreThreadTasks.freeBuffer(); +} + +bool LowPrioThreadMgr::startThread(const LowPrioThreadMgr::InitArg& initArg) { + const u32 num_cores = sead::CoreInfo::getNumCores(); + + mCoreThreadTasks.tryAllocBuffer(num_cores, initArg.heap); + + for (u32 i = 0; i < num_cores; i++) { + auto* task_mgr = new (initArg.heap) TaskMgr(initArg.heap); + task_mgr->init(initArg.queue_size, initArg.heap); + mCoreThreadTasks[i].task_mgr = task_mgr; + + sead::SafeString name; + auto* new_thread = new (initArg.heap) TaskThread( + name, initArg.heap, sead::ThreadUtil::ConvertPrioritySeadToPlatform(initArg.priority), + sead::MessageQueue::BlockType::Blocking, std::numeric_limits::max(), 0x100000, 32); + + { + TaskThread::InitArg arg; + + arg.queue = nullptr; + arg.heap = initArg.heap; + arg.num_lanes = 3; + arg.batch_size = 1; + + new_thread->init(arg); + } + + mCoreThreadTasks[i].task_thread = new_thread; + + new_thread->setAffinity(sead::CoreIdMask(i)); + new_thread->start(); + } + + return true; +} + +bool LowPrioThreadMgr::submitRequest(const LowPrioThreadMgr::Request& request) { + const s32 num_tasks = mCoreThreadTasks.size(); + const sead::BitFlag32 mask = request.flags; + s32 thread_idx = -1; + s32 min = std::numeric_limits::max(); + + for (s32 i = 0; i < num_tasks; i++) { + if (mask.isOnBit(i) && mCoreThreadTasks[i].task_thread) { + s32 active_tasks = mCoreThreadTasks[i].task_thread->getNumActiveTasks(); + + if (active_tasks < min) { + thread_idx = i; + min = active_tasks; + } + } + } + + TaskRequest taskRequest(false); + taskRequest.mPostRunCallback = request.post_callback; + taskRequest.mRemoveCallback = request.remove_callback; + taskRequest.mName = request.name; + taskRequest.mUserData = request.user_data; + taskRequest.mDelegate = request.delegate; + taskRequest.mHasHandle = true; + taskRequest.mSynchronous = false; + taskRequest.mLaneId = request.lane_id; + taskRequest.mThread = mCoreThreadTasks[thread_idx].task_thread; + + TaskMgrRequest mgrRequest; + mgrRequest.handle = request.handle; + mgrRequest.request = &taskRequest; + mgrRequest.task = request.task; + + TaskMgr* task_mgr = request.mgr ? request.mgr : mCoreThreadTasks[thread_idx].task_mgr; + + if (request.try_submit) { + return task_mgr->trySubmitRequest(mgrRequest); + } + + task_mgr->submitRequest(mgrRequest); + return true; +} + +void LowPrioThreadMgr::pauseAllTasks() { + const s32 num_tasks = mCoreThreadTasks.size(); + + for (s32 i = 0; i < num_tasks; i++) { + mCoreThreadTasks[i].task_thread->pauseAndWaitForAck(); + } +} + +void LowPrioThreadMgr::resumeAllTasks() { + const s32 num_tasks = mCoreThreadTasks.size(); + + for (s32 i = 0; i < num_tasks; i++) { + mCoreThreadTasks[i].task_thread->resume(); + } +} + +void LowPrioThreadMgr::sub_710127AC40() {} + +} // namespace ksys::util -- cgit v1.2.3