mirror of https://github.com/zeldaret/botw.git
ksys/frm: Implement WorkerSupportThreadMgr
This commit is contained in:
parent
caa3dcf548
commit
927c757345
|
|
@ -39801,7 +39801,7 @@
|
|||
0x000000710065a290,sub_710065A290,8,
|
||||
0x000000710065a298,sub_710065A298,48,
|
||||
0x000000710065a2c8,sub_710065A2C8,92,
|
||||
0x000000710065a324,sub_710065A324,8,
|
||||
0x000000710065a324,sub_710065A324,8,_ZNK4sead10IDelegate2IPNS_6ThreadElE9isNoDummyEv
|
||||
0x000000710065a32c,sub_710065A32C,8,_ZNK4sead10IDelegate2IPNS_6ThreadElE5cloneEPNS_4HeapE
|
||||
0x000000710065a334,sub_710065A334,48,
|
||||
0x000000710065a364,sub_710065A364,92,
|
||||
|
|
@ -75989,19 +75989,19 @@
|
|||
0x0000007100dcde30,sub_7100DCDE30,92,
|
||||
0x0000007100dcde8c,sub_7100DCDE8C,52,
|
||||
0x0000007100dcdec0,sub_7100DCDEC0,92,
|
||||
0x0000007100dcdf1c,sub_7100DCDF1C,56,
|
||||
0x0000007100dcdf54,sub_7100DCDF54,92,
|
||||
0x0000007100dcdfb0,WorkerSupportThreadMgr::createInstance,276,
|
||||
0x0000007100dce0c4,WorkerSupportThreadMgr::init,656,
|
||||
0x0000007100dce354,WorkerSupportThreadMgr::startSleeperThread,588,
|
||||
0x0000007100dce5a0,SleeperThreadFunc,44,
|
||||
0x0000007100dce5cc,WorkerSupportThreadMgr::submitReq,240,
|
||||
0x0000007100dce6bc,WorkerSupportThreadMgr::__auto0,68,
|
||||
0x0000007100dce700,WorkerSupportThreadMgr::__auto3,48,
|
||||
0x0000007100dce730,WorkerSupportThreadMgr::__auto1,44,
|
||||
0x0000007100dce75c,WorkerSupportThreadMgr::__auto2,136,
|
||||
0x0000007100dce7e8,sub_7100DCE7E8,48,
|
||||
0x0000007100dce818,sub_7100DCE818,92,
|
||||
0x0000007100dcdf1c,sub_7100DCDF1C,56,_ZN4ksys3frm22WorkerSupportThreadMgr18SingletonDisposer_D1Ev
|
||||
0x0000007100dcdf54,sub_7100DCDF54,92,_ZN4ksys3frm22WorkerSupportThreadMgr18SingletonDisposer_D0Ev
|
||||
0x0000007100dcdfb0,WorkerSupportThreadMgr::createInstance,276,_ZN4ksys3frm22WorkerSupportThreadMgr14createInstanceEPN4sead4HeapE
|
||||
0x0000007100dce0c4,WorkerSupportThreadMgr::init,656,_ZN4ksys3frm22WorkerSupportThreadMgr4initEPN4sead4HeapE
|
||||
0x0000007100dce354,WorkerSupportThreadMgr::startSleeperThread,588,_ZN4ksys3frm22WorkerSupportThreadMgr18initSleeperThreadsEv
|
||||
0x0000007100dce5a0,SleeperThreadFunc,44,_ZN4ksys3frm22WorkerSupportThreadMgr16sleeperThreadFunEPN4sead6ThreadEl
|
||||
0x0000007100dce5cc,WorkerSupportThreadMgr::submitReq,240,_ZN4ksys3frm22WorkerSupportThreadMgr13submitRequestEiPN4sead11IDelegate1RIPvbEE
|
||||
0x0000007100dce6bc,WorkerSupportThreadMgr::__auto0,68,_ZN4ksys3frm22WorkerSupportThreadMgr11waitForTaskEi
|
||||
0x0000007100dce700,WorkerSupportThreadMgr::__auto3,48,_ZN4ksys3frm22WorkerSupportThreadMgr12pauseThreadsEv
|
||||
0x0000007100dce730,WorkerSupportThreadMgr::__auto1,44,_ZN4ksys3frm22WorkerSupportThreadMgr13resumeThreadsEv
|
||||
0x0000007100dce75c,WorkerSupportThreadMgr::__auto2,136,_ZN4ksys3frm22WorkerSupportThreadMgr14destroyThreadsEv
|
||||
0x0000007100dce7e8,sub_7100DCE7E8,48,_ZN4sead9Delegate2IN4ksys3frm22WorkerSupportThreadMgrEPNS_6ThreadElE6invokeES5_l
|
||||
0x0000007100dce818,sub_7100DCE818,92,_ZNK4sead9Delegate2IN4ksys3frm22WorkerSupportThreadMgrEPNS_6ThreadElE5cloneEPNS_4HeapE
|
||||
0x0000007100dce874,sub_7100DCE874,32,
|
||||
0x0000007100dce894,sub_7100DCE894,100,_ZN4ksys3gdt7Manager18SingletonDisposer_D1Ev
|
||||
0x0000007100dce8f8,sub_7100DCE8F8,108,_ZN4ksys3gdt7Manager18SingletonDisposer_D0Ev
|
||||
|
|
|
|||
|
Can't render this file because it is too large.
|
|
|
@ -1,3 +1,5 @@
|
|||
target_sources(uking PRIVATE
|
||||
frmRootTaskParam.h
|
||||
frmWorkerSupportThreadMgr.cpp
|
||||
frmWorkerSupportThreadMgr.h
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,138 @@
|
|||
#include "KingSystem/Framework/frmWorkerSupportThreadMgr.h"
|
||||
#include <mc/seadCoreInfo.h>
|
||||
#include <thread/seadDelegateThread.h>
|
||||
#include <thread/seadThreadUtil.h>
|
||||
#include "KingSystem/Utils/SafeDelete.h"
|
||||
#include "KingSystem/Utils/Thread/GameTaskThread.h"
|
||||
#include "KingSystem/Utils/Thread/ManagedTask.h"
|
||||
#include "KingSystem/Utils/Thread/ManagedTaskHandle.h"
|
||||
#include "KingSystem/Utils/Thread/TaskMgr.h"
|
||||
|
||||
namespace ksys::frm {
|
||||
|
||||
SEAD_SINGLETON_DISPOSER_IMPL(WorkerSupportThreadMgr)
|
||||
|
||||
void WorkerSupportThreadMgr::init(sead::Heap* heap) {
|
||||
auto* worker = mWorkers;
|
||||
for (size_t i = 0; i < NumWorkers; ++i) {
|
||||
auto* mgr = new (heap) util::TaskMgr(heap);
|
||||
mgr->init<util::ManagedTask>(NumTasks, heap);
|
||||
worker->task_mgr = mgr;
|
||||
|
||||
worker->task_handle = new (heap) util::ManagedTaskHandle;
|
||||
for (int j = 0; j < NumTasks; ++j)
|
||||
worker->tasks[j] = new (heap) util::ManagedTask(heap);
|
||||
|
||||
const auto affinity = [&] {
|
||||
if (i == 0)
|
||||
return sead::CoreIdMask(sead::CoreId::cSub1);
|
||||
return sead::CoreIdMask(sead::CoreId::cSub2);
|
||||
}();
|
||||
|
||||
worker->thread_name.format("WorkerSupport[%d]", int(i));
|
||||
worker->task_thread = new (heap) util::GameTaskThread(
|
||||
worker->thread_name, heap, sead::ThreadUtil::ConvertPrioritySeadToPlatform(17),
|
||||
sead::MessageQueue::BlockType::Blocking, 0x7fffffff, 0x20000, 32);
|
||||
|
||||
util::TaskThread::InitArg arg;
|
||||
arg.batch_size = 0;
|
||||
arg.heap = nullptr;
|
||||
arg.queue = nullptr;
|
||||
arg.heap = heap;
|
||||
arg.num_lanes = 1;
|
||||
worker->task_thread->init(arg);
|
||||
worker->task_thread->setAffinity(affinity);
|
||||
worker->task_thread->start();
|
||||
++worker;
|
||||
}
|
||||
|
||||
mSleeperHeap = sead::ExpHeap::create(0x8000, "SleeperHeap", heap, sizeof(void*),
|
||||
sead::Heap::cHeapDirection_Forward, false);
|
||||
initSleeperThreads();
|
||||
mSleeperHeap->adjust();
|
||||
}
|
||||
|
||||
void WorkerSupportThreadMgr::initSleeperThreads() {
|
||||
for (int i = 0; i < NumWorkers; ++i) {
|
||||
const sead::CoreIdMask affinity{sead::CoreId::cSub1 + i};
|
||||
if (affinity == sead::CoreIdMask(sead::CoreId::cSub2)) {
|
||||
mWorkers[i].thread = new (mSleeperHeap) sead::DelegateThread(
|
||||
"Sleeper",
|
||||
new (mSleeperHeap) sead::Delegate2<WorkerSupportThreadMgr, sead::Thread*,
|
||||
sead::MessageQueue::Element>(
|
||||
this, &WorkerSupportThreadMgr::sleeperThreadFun),
|
||||
mSleeperHeap, sead::ThreadUtil::ConvertPrioritySeadToPlatform(15),
|
||||
sead::MessageQueue::BlockType::NonBlocking, 0x7fffffff, 0x1000, 32);
|
||||
mWorkers[i].thread->setAffinity(affinity);
|
||||
mWorkers[i].thread->start();
|
||||
mWorkers[i].thread->sendMessage(1, sead::MessageQueue::BlockType::NonBlocking);
|
||||
} else {
|
||||
mWorkers[i].thread = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorkerSupportThreadMgr::sleeperThreadFun(sead::Thread* thread, sead::MessageQueue::Element) {
|
||||
sead::Thread::sleep(sead::TickSpan::fromMicroSeconds(250));
|
||||
}
|
||||
|
||||
static int getWorkerIdx(u32 id) {
|
||||
return (id == 1 || id == 4 || id == 6 || id == 3 || id == 7) ? 1 : 0;
|
||||
}
|
||||
|
||||
static int getTaskIdx(u32 id) {
|
||||
static constexpr u8 idx[] = {0, 0, 1, 1, 2, 2, 3, 4};
|
||||
return idx[id];
|
||||
}
|
||||
|
||||
util::ManagedTask* WorkerSupportThreadMgr::getTask(int id) {
|
||||
return mWorkers[getWorkerIdx(id)].tasks[getTaskIdx(id)];
|
||||
}
|
||||
|
||||
void WorkerSupportThreadMgr::submitRequest(int id, util::TaskDelegate* delegate) {
|
||||
auto& worker = mWorkers[getWorkerIdx(id)];
|
||||
if (mThreadsPaused)
|
||||
return;
|
||||
|
||||
util::TaskRequest req{false};
|
||||
req.mName = worker.thread_name;
|
||||
req.mDelegate = delegate;
|
||||
req.mHasHandle = true;
|
||||
req.mSynchronous = false;
|
||||
req.mThread = worker.task_thread;
|
||||
|
||||
util::TaskMgrRequest task_mgr_req;
|
||||
task_mgr_req.request = &req;
|
||||
task_mgr_req.handle = worker.task_handle;
|
||||
task_mgr_req.task = worker.tasks[getTaskIdx(id)];
|
||||
worker.task_mgr->submitRequest(task_mgr_req);
|
||||
}
|
||||
|
||||
void WorkerSupportThreadMgr::waitForTask(int id) {
|
||||
if (!mThreadsPaused)
|
||||
getTask(id)->wait();
|
||||
}
|
||||
|
||||
void WorkerSupportThreadMgr::pauseThreads() {
|
||||
mThreadsPaused = true;
|
||||
for (auto& worker : mWorkers)
|
||||
worker.task_thread->pauseAndWaitForAck();
|
||||
}
|
||||
|
||||
void WorkerSupportThreadMgr::resumeThreads() {
|
||||
mThreadsPaused = false;
|
||||
for (auto& worker : mWorkers)
|
||||
worker.task_thread->resume();
|
||||
}
|
||||
|
||||
void WorkerSupportThreadMgr::destroyThreads() {
|
||||
for (auto& worker : mWorkers) {
|
||||
if (worker.thread) {
|
||||
worker.thread->quitAndDestroySingleThread(false);
|
||||
util::safeDelete(worker.thread);
|
||||
}
|
||||
}
|
||||
mSleeperHeap->freeAll();
|
||||
}
|
||||
|
||||
} // namespace ksys::frm
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
#pragma once
|
||||
|
||||
#include <heap/seadDisposer.h>
|
||||
#include <prim/seadSafeString.h>
|
||||
#include <thread/seadMessageQueue.h>
|
||||
#include "KingSystem/Utils/Thread/Task.h"
|
||||
#include "KingSystem/Utils/Types.h"
|
||||
|
||||
namespace sead {
|
||||
class DelegateThread;
|
||||
class Thread;
|
||||
} // namespace sead
|
||||
|
||||
namespace ksys::util {
|
||||
class GameTaskThread;
|
||||
class ManagedTask;
|
||||
class ManagedTaskHandle;
|
||||
class TaskMgr;
|
||||
} // namespace ksys::util
|
||||
|
||||
namespace ksys::frm {
|
||||
|
||||
class WorkerSupportThreadMgr {
|
||||
SEAD_SINGLETON_DISPOSER(WorkerSupportThreadMgr)
|
||||
WorkerSupportThreadMgr() = default;
|
||||
~WorkerSupportThreadMgr() = default;
|
||||
|
||||
public:
|
||||
enum class Owner {
|
||||
_0,
|
||||
_1,
|
||||
_2,
|
||||
_3,
|
||||
_4,
|
||||
_5,
|
||||
_6,
|
||||
_7,
|
||||
};
|
||||
|
||||
void init(sead::Heap* heap);
|
||||
|
||||
void submitRequest(int id, util::TaskDelegate* delegate);
|
||||
void waitForTask(int id);
|
||||
void pauseThreads();
|
||||
void resumeThreads();
|
||||
void destroyThreads();
|
||||
|
||||
private:
|
||||
static constexpr int NumWorkers = 2;
|
||||
static constexpr int NumTasks = 5;
|
||||
|
||||
struct Worker {
|
||||
util::GameTaskThread* task_thread = nullptr;
|
||||
sead::DelegateThread* thread;
|
||||
util::ManagedTask* tasks[NumTasks];
|
||||
util::TaskMgr* task_mgr = nullptr;
|
||||
util::ManagedTaskHandle* task_handle;
|
||||
sead::FixedSafeString<32> thread_name;
|
||||
};
|
||||
|
||||
void initSleeperThreads();
|
||||
void sleeperThreadFun(sead::Thread* thread, sead::MessageQueue::Element);
|
||||
|
||||
util::ManagedTask* getTask(int id);
|
||||
|
||||
Worker mWorkers[NumWorkers];
|
||||
bool mThreadsPaused = false;
|
||||
sead::Heap* mSleeperHeap;
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(WorkerSupportThreadMgr, 0x130);
|
||||
|
||||
} // namespace ksys::frm
|
||||
Loading…
Reference in New Issue