diff options
| author | Léo Lam <leo@leolam.fr> | 2021-03-07 15:43:59 +0100 |
|---|---|---|
| committer | Léo Lam <leo@leolam.fr> | 2021-03-11 21:59:56 +0100 |
| commit | 69c78356b3f193b39e86f2a5aaf31ce82cc2e768 (patch) | |
| tree | bf3848b4928cb1c5f3dd8dbe873a2bc0debba579 /src/KingSystem/ActorSystem/actBaseProcJobQue.cpp | |
| parent | b15b12e7c4eb23ec07a7cd437b8a144d8fba362c (diff) | |
ksys/act: Add BaseProcJob and BaseProcJobQue
Diffstat (limited to 'src/KingSystem/ActorSystem/actBaseProcJobQue.cpp')
| -rw-r--r-- | src/KingSystem/ActorSystem/actBaseProcJobQue.cpp | 127 |
1 files changed, 127 insertions, 0 deletions
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 <mc/seadWorkerMgr.h> +#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<BaseProcJobLink*>(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<BaseProcJobLink*>(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<BaseProcJobLink*>(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<BaseProcJobLink*>(list.front()); link; + link = static_cast<BaseProcJobLink*>(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<BaseProcJobLink>& 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 |
