summaryrefslogtreecommitdiff
path: root/src/KingSystem/ActorSystem/actBaseProcJobQue.cpp
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2021-03-07 15:43:59 +0100
committerLéo Lam <leo@leolam.fr>2021-03-11 21:59:56 +0100
commit69c78356b3f193b39e86f2a5aaf31ce82cc2e768 (patch)
treebf3848b4928cb1c5f3dd8dbe873a2bc0debba579 /src/KingSystem/ActorSystem/actBaseProcJobQue.cpp
parentb15b12e7c4eb23ec07a7cd437b8a144d8fba362c (diff)
ksys/act: Add BaseProcJob and BaseProcJobQue
Diffstat (limited to 'src/KingSystem/ActorSystem/actBaseProcJobQue.cpp')
-rw-r--r--src/KingSystem/ActorSystem/actBaseProcJobQue.cpp127
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