From 69c78356b3f193b39e86f2a5aaf31ce82cc2e768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 7 Mar 2021 15:43:59 +0100 Subject: [PATCH] ksys/act: Add BaseProcJob and BaseProcJobQue --- data/uking_functions.csv | 40 +++--- lib/sead | 2 +- src/KingSystem/ActorSystem/CMakeLists.txt | 2 + src/KingSystem/ActorSystem/actBaseProc.h | 5 + src/KingSystem/ActorSystem/actBaseProcJob.cpp | 5 + src/KingSystem/ActorSystem/actBaseProcJob.h | 22 +++ .../ActorSystem/actBaseProcJobQue.cpp | 127 ++++++++++++++++++ .../ActorSystem/actBaseProcJobQue.h | 58 ++++++++ 8 files changed, 240 insertions(+), 21 deletions(-) create mode 100644 src/KingSystem/ActorSystem/actBaseProcJobQue.cpp create mode 100644 src/KingSystem/ActorSystem/actBaseProcJobQue.h diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 7d17549e..b398c134 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -96993,16 +96993,16 @@ 0x0000007101306760,BaseProcEvent::Request::dtorDelete,4, 0x0000007101306764,BaseProcEvent::make,60, 0x00000071013067a0,sub_71013067A0,64, -0x00000071013067e0,BaseProcJobQue::ctor,160, -0x0000007101306880,BaseProcJobQue::dtor,108, -0x00000071013068ec,BaseProcJobQue::dtorDelete,116, -0x0000007101306960,BaseProcJobQue::init,116, -0x00000071013069d4,BaseProcJobQue::pushJobQueue,208, -0x0000007101306aa4,BaseProcJobQue::pushJobs,516, -0x0000007101306ca8,BaseProcJobQue::pushJobsUsingExtraArrays,288, -0x0000007101306dc8,BaseProcJobQue::pushExtraJobs,180, -0x0000007101306e7c,BaseProcJob::invoke,28, -0x0000007101306e98,BaseProcJob::dtorDelete,36, +0x00000071013067e0,BaseProcJobQue::ctor,160,_ZN4ksys3act14BaseProcJobQueC1Ev +0x0000007101306880,BaseProcJobQue::dtor,108,_ZN4ksys3act14BaseProcJobQueD1Ev +0x00000071013068ec,BaseProcJobQue::dtorDelete,116,_ZN4ksys3act14BaseProcJobQueD0Ev +0x0000007101306960,BaseProcJobQue::init,116,_ZN4ksys3act14BaseProcJobQue4initEPN4sead4HeapE +0x00000071013069d4,BaseProcJobQue::pushJobQueue,208,_ZN4ksys3act14BaseProcJobQue12pushJobQueueEPN4sead9WorkerMgrEPNS0_16BaseProcJobListsEiNS0_7JobTypeE +0x0000007101306aa4,BaseProcJobQue::pushJobs,516,_ZN4ksys3act14BaseProcJobQue8pushJobsEPN4sead11FixedSizeJQEPNS0_16BaseProcJobListsEibNS0_7JobTypeE +0x0000007101306ca8,BaseProcJobQue::pushJobsUsingExtraArrays,288,_ZN4ksys3act14BaseProcJobQue13pushExtraJobsEPN4sead11FixedSizeJQEPNS0_16BaseProcJobListsEiNS0_7JobTypeE? +0x0000007101306dc8,BaseProcJobQue::pushExtraJobs,180,_ZN4ksys3act14BaseProcJobQue13pushExtraJobsEPN4sead11FixedSizeJQERKN3agl3utl14AtomicPtrArrayINS0_15BaseProcJobLinkEEE +0x0000007101306e7c,BaseProcJob::invoke,28,_ZN4ksys3act11BaseProcJob6invokeEv +0x0000007101306e98,BaseProcJob::dtorDelete,36,_ZN4ksys3act11BaseProcJobD0Ev 0x0000007101306ebc,sub_7101306EBC,80, 0x0000007101306f0c,sub_7101306F0C,256, 0x000000710130700c,sub_710130700C,264, @@ -99439,16 +99439,16 @@ 0x000000710136ef7c,sead::Worker::m19,580, 0x000000710136f1c0,_ZN4sead6WorkerD2Ev,64,_ZN4sead6WorkerD2Ev 0x000000710136f200,sead::Worker::m1,72, -0x000000710136f248,_ZN4sead9WorkerMgrC2Ev,192, -0x000000710136f308,j__ZN2nn2os13GetSystemTickEv_0_0,4, -0x000000710136f30c,_ZN4sead9WorkerMgr13InitializeArgC2Ev,56, -0x000000710136f344,_ZN4sead9WorkerMgr10initializeERKNS0_13InitializeArgE,648, -0x000000710136f5cc,_ZN4sead9WorkerMgr12pushJobQueueEPNS_8JobQueueENS_10CoreIdMaskENS_8SyncTypeENS_16JobQueuePushTypeE,256, -0x000000710136f6cc,_ZN4sead9WorkerMgr12pushJobQueueEPKcPNS_8JobQueueENS_10CoreIdMaskENS_8SyncTypeENS_16JobQueuePushTypeE,252, -0x000000710136f7c8,_ZN4sead9WorkerMgr3runEv,448, -0x000000710136f988,_ZN4sead9WorkerMgr4syncEv,304, -0x000000710136fab8,_ZN4sead9WorkerMgrD2Ev,120, -0x000000710136fb30,sead::WorkerMgr::dtorDelete,128, +0x000000710136f248,_ZN4sead9WorkerMgrC1Ev,192,_ZN4sead9WorkerMgrC1Ev? +0x000000710136f308,j__ZN2nn2os13GetSystemTickEv_0_0,4,_ZN4sead9WorkerMgr10onInfLoop_ERKNS_14InfLoopChecker12InfLoopParamE +0x000000710136f30c,_ZN4sead9WorkerMgr13InitializeArgC2Ev,56,_ZN4sead9WorkerMgr13InitializeArgC1Ev +0x000000710136f344,_ZN4sead9WorkerMgr10initializeERKNS0_13InitializeArgE,648,_ZN4sead9WorkerMgr10initializeERKNS0_13InitializeArgE +0x000000710136f5cc,_ZN4sead9WorkerMgr12pushJobQueueEPNS_8JobQueueENS_10CoreIdMaskENS_8SyncTypeENS_16JobQueuePushTypeE,256,_ZN4sead9WorkerMgr12pushJobQueueEPNS_8JobQueueENS_10CoreIdMaskENS_8SyncTypeENS_16JobQueuePushTypeE +0x000000710136f6cc,_ZN4sead9WorkerMgr12pushJobQueueEPKcPNS_8JobQueueENS_10CoreIdMaskENS_8SyncTypeENS_16JobQueuePushTypeE,252,_ZN4sead9WorkerMgr12pushJobQueueEPKcPNS_8JobQueueENS_10CoreIdMaskENS_8SyncTypeENS_16JobQueuePushTypeE +0x000000710136f7c8,_ZN4sead9WorkerMgr3runEv,448,_ZN4sead9WorkerMgr3runEv +0x000000710136f988,_ZN4sead9WorkerMgr4syncEv,304,_ZN4sead9WorkerMgr4syncEv +0x000000710136fab8,_ZN4sead9WorkerMgrD1Ev,120,_ZN4sead9WorkerMgrD1Ev +0x000000710136fb30,sead::WorkerMgr::dtorDelete,128,_ZN4sead9WorkerMgrD0Ev 0x000000710136fbb0,sub_710136FBB0,48, 0x000000710136fbe0,sub_710136FBE0,92, 0x000000710136fc3c,LMS_InitMessage,164, diff --git a/lib/sead b/lib/sead index a88c0975..96285598 160000 --- a/lib/sead +++ b/lib/sead @@ -1 +1 @@ -Subproject commit a88c0975cef13aa1ace83d9a829df963da1594e3 +Subproject commit 96285598f5738a3e916707c535ed6d772764aae2 diff --git a/src/KingSystem/ActorSystem/CMakeLists.txt b/src/KingSystem/ActorSystem/CMakeLists.txt index 92fec072..7d40b8c5 100644 --- a/src/KingSystem/ActorSystem/CMakeLists.txt +++ b/src/KingSystem/ActorSystem/CMakeLists.txt @@ -60,6 +60,8 @@ target_sources(uking PRIVATE actBaseProcJob.h actBaseProcJobHandler.cpp actBaseProcJobHandler.h + actBaseProcJobQue.cpp + actBaseProcJobQue.h actBaseProcLink.cpp actBaseProcLink.h actBaseProcMap.cpp diff --git a/src/KingSystem/ActorSystem/actBaseProc.h b/src/KingSystem/ActorSystem/actBaseProc.h index 008d31b4..ae81149c 100644 --- a/src/KingSystem/ActorSystem/actBaseProc.h +++ b/src/KingSystem/ActorSystem/actBaseProc.h @@ -122,6 +122,11 @@ public: void setCreatePriorityState2(); bool setStateFlag(u32 flag_bit); + void onJobPush(JobType type) { + onJobPush1_(type); + onJobPush2_(type); + } + protected: friend class BaseProcLinkDataMgr; friend class BaseProcMgr; diff --git a/src/KingSystem/ActorSystem/actBaseProcJob.cpp b/src/KingSystem/ActorSystem/actBaseProcJob.cpp index 6e23eec2..1c64e5ee 100644 --- a/src/KingSystem/ActorSystem/actBaseProcJob.cpp +++ b/src/KingSystem/ActorSystem/actBaseProcJob.cpp @@ -1,4 +1,5 @@ #include "KingSystem/ActorSystem/actBaseProcJob.h" +#include "KingSystem/ActorSystem/actBaseProcMgr.h" #include "KingSystem/Utils/InitTimeInfo.h" namespace ksys::act { @@ -74,4 +75,8 @@ sead::TListNode* BaseProcJobLists::getNextJob(BaseProcJobLink* link) return mLists[link->getPriority()].next(link); } +void BaseProcJob::invoke() { + BaseProcMgr::instance()->jobInvoked(mJobLink, mRequiredCalcRounds); +} + } // namespace ksys::act diff --git a/src/KingSystem/ActorSystem/actBaseProcJob.h b/src/KingSystem/ActorSystem/actBaseProcJob.h index e598442d..705bbb38 100644 --- a/src/KingSystem/ActorSystem/actBaseProcJob.h +++ b/src/KingSystem/ActorSystem/actBaseProcJob.h @@ -2,6 +2,7 @@ #include #include +#include #include "KingSystem/Utils/Types.h" namespace ksys::act { @@ -30,6 +31,8 @@ class BaseProcJobLink : public sead::TListNode { public: BaseProcJobLink(BaseProc* proc, u8 priority); + BaseProc* getProc() const { return mData; } + u8 getPriority() const { return mPriority; } u8 getPriority2() const { return mPriority2; } @@ -66,9 +69,28 @@ public: sead::TListNode* getJobWithTopPriority() const; sead::TListNode* getNextJobWithTopPriority(BaseProcJobLink* link) const; sead::TListNode* getNextJob(BaseProcJobLink* link) const; + BaseProcJobList& getList(int idx) { return mLists[idx]; } + const BaseProcJobList& getList(int idx) const { return mLists[idx]; } private: sead::SafeArray mLists; }; +class BaseProcJob final : public sead::Job { +public: + BaseProcJob() = default; + void invoke() override; + + void set(BaseProcJobLink* link, int rounds) { + mJobLink = link; + mRequiredCalcRounds = rounds; + } + +private: + friend class BaseProcJobQue; + + BaseProcJobLink* mJobLink = nullptr; + int mRequiredCalcRounds = 0; +}; + } // namespace ksys::act diff --git a/src/KingSystem/ActorSystem/actBaseProcJobQue.cpp b/src/KingSystem/ActorSystem/actBaseProcJobQue.cpp new file mode 100644 index 00000000..efa623a1 --- /dev/null +++ b/src/KingSystem/ActorSystem/actBaseProcJobQue.cpp @@ -0,0 +1,127 @@ +#include "KingSystem/ActorSystem/actBaseProcJobQue.h" +#include +#include "KingSystem/ActorSystem/actBaseProc.h" + +namespace ksys::act { + +BaseProcJobQue::BaseProcJobQue() = default; + +BaseProcJobQue::~BaseProcJobQue() { + mJobQueue.clear(); +} + +void BaseProcJobQue::init(sead::Heap* heap) { + mJobQueue.initialize(mPool.size(), heap); + mJobQueue.clear(); + for (u32 i = 0; i < sead::CoreInfo::getNumCores(); ++i) + mJobQueue.setGranularity(i, 1); +} + +bool BaseProcJobQue::pushJobQueue(sead::WorkerMgr* worker_mgr, BaseProcJobLists* lists, + int priority, JobType type) { + mJobQueue.clear(); + const bool ok = pushJobs(&mJobQueue, lists, priority, true, type); + if (ok) { + sead::CoreIdMask cores{sead::CoreId::cMain, sead::CoreId::cSub1, sead::CoreId::cSub2}; + worker_mgr->pushJobQueue("BaseProcJobQue::pushJobQueue", &mJobQueue, cores, + sead::SyncType::cNoSync, sead::JobQueuePushType::cForward); + } + return ok; +} + +bool BaseProcJobQue::pushJobs(sead::FixedSizeJQ* queue, BaseProcJobLists* lists, int priority, + bool should_reset_job_idx, JobType type) { + if (should_reset_job_idx) + mFreeJobIdx = 0; + + const auto& list = lists->getList(priority); + const int num_jobs = list.size(); + int num_remaining_jobs = num_jobs; + if (num_jobs == 0) + return false; + + const int capacity = int(mPool.size() / 2); + + const int num_free = capacity - mFreeJobIdx; + if (num_free <= 0) + return false; + + auto* link = static_cast(list.front()); + + if (num_remaining_jobs > num_free) { + if (num_remaining_jobs <= 0) + return true; + + int rounds = num_remaining_jobs / num_free + 1; + do { + auto* const batch_head = link; + + for (int i = 1; link && i <= rounds; ++i) + link = static_cast(lists->getNextJob(link)); + + mPool[mFreeJobIdx].set(batch_head, rounds); + queue->enque(&mPool[mFreeJobIdx]); + num_remaining_jobs -= rounds; + rounds = std::min(rounds, num_remaining_jobs); + ++mFreeJobIdx; + } while (num_remaining_jobs > 0 && num_remaining_jobs > capacity - mFreeJobIdx); + } + + for (int i = 1; link && i <= num_remaining_jobs; ++i) { + link->getProc()->onJobPush(type); + if (!link->getProc()->shouldSkipJobPush(type)) { + mPool[mFreeJobIdx].set(link, 1); + queue->enque(&mPool[mFreeJobIdx]); + ++mFreeJobIdx; + } + link = static_cast(lists->getNextJob(link)); + } + + return true; +} + +// NON_MATCHING: sxtw + madd -> smaddl +bool BaseProcJobQue::pushExtraJobs(sead::FixedSizeJQ* queue, BaseProcJobLists* lists, int priority, + JobType type) { + const auto& list = lists->getList(priority); + if (list.size() == 0) + return false; + + for (auto* link = static_cast(list.front()); link; + link = static_cast(lists->getNextJob(link))) { + const auto idx = mNumExtraJobs.increment(); + if (idx >= mPool.size()) + return false; + + link->getProc()->onJobPush(type); + + if (!link->getProc()->shouldSkipJobPush(type)) { + mPool[idx].set(link, 1); + if (!queue->enque(&mPool[idx])) + return false; + } + } + + return true; +} + +bool BaseProcJobQue::pushExtraJobs(sead::FixedSizeJQ* queue, + const agl::utl::AtomicPtrArray& links) { + if (links.size() <= 0) + return false; + + for (auto it = links.begin(), end = links.end(); it != end; ++it) { + const auto idx = mNumExtraJobs.increment(); + if (idx >= mPool.size()) + return false; + + mPool[idx].mJobLink = &*it; + mPool[idx].mRequiredCalcRounds = 1; + if (!queue->enque(&mPool[idx])) + return false; + } + + return true; +} + +} // namespace ksys::act diff --git a/src/KingSystem/ActorSystem/actBaseProcJobQue.h b/src/KingSystem/ActorSystem/actBaseProcJobQue.h new file mode 100644 index 00000000..9a5dc27a --- /dev/null +++ b/src/KingSystem/ActorSystem/actBaseProcJobQue.h @@ -0,0 +1,58 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include "KingSystem/ActorSystem/actBaseProcJob.h" +#include "KingSystem/Utils/Types.h" + +namespace sead { +class WorkerMgr; +} + +namespace ksys::act { + +class BaseProcJobQue { +public: + BaseProcJobQue(); + BaseProcJobQue(const BaseProcJobQue&) = delete; + auto operator=(const BaseProcJobQue&) = delete; + virtual ~BaseProcJobQue(); + + void init(sead::Heap* heap); + bool pushJobQueue(sead::WorkerMgr* worker_mgr, BaseProcJobLists* lists, int priority, + JobType type); + bool pushExtraJobs(sead::FixedSizeJQ* queue, BaseProcJobLists* lists, int priority, + JobType type); + bool pushExtraJobs(sead::FixedSizeJQ* queue, + const agl::utl::AtomicPtrArray& links); + +private: + bool pushJobs(sead::FixedSizeJQ* queue, BaseProcJobLists* lists, int priority, + bool should_reset_job_idx, JobType type); + + struct Pool { + Pool() { + for (auto& job : mPool) + job.constructDefault(); + } + + u32 size() const { return u32(mPool.size()); } + auto& operator[](int idx) { return mPool[idx].ref(); } + auto& operator[](int idx) const { return mPool[idx].ref(); } + + std::array, 1200> mPool{}; + }; + + int mFreeJobIdx = 0; + sead::FixedSizeJQ mJobQueue; + Pool mPool; + sead::Atomic mNumExtraJobs = 0; +}; +KSYS_CHECK_SIZE_NX150(BaseProcJobQue, 0xbc38); + +} // namespace ksys::act