summaryrefslogtreecommitdiff
path: root/src/KingSystem/Utils/Thread/TaskMgr.h
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2020-09-15 19:13:52 +0200
committerLéo Lam <leo@leolam.fr>2020-09-16 17:49:37 +0200
commit3db6228dfc65a25da49bab26ab8bcf4abc69a98f (patch)
tree3946a9211c2adc7213b1ae94ccf4baca22b73020 /src/KingSystem/Utils/Thread/TaskMgr.h
parent8b7369dffb1e816b2f27ab0133d2bac218383a45 (diff)
ksys: Add more task utilities
* TaskMgr, ManagedTask, ManagedTaskHandle * GameTaskThread: partial implementation because PhysicsMemSys / Havok stuff hasn't been decompiled yet and calc_() requires PhysicsMemSys
Diffstat (limited to 'src/KingSystem/Utils/Thread/TaskMgr.h')
-rw-r--r--src/KingSystem/Utils/Thread/TaskMgr.h88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/KingSystem/Utils/Thread/TaskMgr.h b/src/KingSystem/Utils/Thread/TaskMgr.h
new file mode 100644
index 00000000..76a91ad9
--- /dev/null
+++ b/src/KingSystem/Utils/Thread/TaskMgr.h
@@ -0,0 +1,88 @@
+#pragma once
+
+#include <container/seadBuffer.h>
+#include <container/seadOffsetList.h>
+#include <container/seadSafeArray.h>
+#include <heap/seadDisposer.h>
+#include <prim/seadDelegate.h>
+#include <prim/seadRuntimeTypeInfo.h>
+#include <prim/seadScopedLock.h>
+#include <prim/seadTypedBitFlag.h>
+#include <thread/seadCriticalSection.h>
+#include "KingSystem/Utils/Thread/Event.h"
+#include "KingSystem/Utils/Types.h"
+
+namespace ksys::util {
+
+class ManagedTask;
+class ManagedTaskHandle;
+class TaskRequest;
+struct TaskMgrRequest;
+
+using ManagedTaskFactory = sead::IDelegate1<ManagedTask**>;
+
+struct TaskMgrRequest {
+ /// Optional. If null, a task from the internal buffer will be used.
+ ManagedTask* task;
+ /// Must not be null.
+ TaskRequest* request;
+ /// Optional.
+ ManagedTaskHandle* handle;
+};
+KSYS_CHECK_SIZE_NX150(TaskMgrRequest, 0x18);
+
+class TaskMgr {
+ SEAD_RTTI_BASE(TaskMgr)
+public:
+ explicit TaskMgr(sead::Heap* heap);
+ virtual ~TaskMgr();
+
+ void init(s32 num_tasks, sead::Heap* heap, ManagedTaskFactory& factory);
+ void finalize();
+
+ void submitRequest(TaskMgrRequest& request);
+ bool trySubmitRequest(TaskMgrRequest& request);
+
+ bool hasTasks() const;
+
+ void freeTask(ManagedTask* task);
+
+protected:
+ enum class Flag {
+ HeapIsFreeable = 0x1,
+ };
+
+ bool fetchIdleTaskForRequest_(TaskMgrRequest& request, bool retry_until_success);
+ ManagedTask* fetchIdleTask_(bool retry_until_success);
+
+ u8 getListIndex_() const { return mListIndex; }
+ u8 getListIndex2_() const { return ~mListIndex & 1; }
+
+ void swapLists_() {
+ auto lock = sead::makeScopedLock(mCS2);
+ mListIndex = getListIndex2_();
+ mNewFreeTaskEvent.resetSignal();
+ }
+
+ bool tryFetchTaskForRequest_(TaskMgrRequest& request, bool b) {
+ if (!mTasksCS.tryLock())
+ return false;
+
+ const bool ret = fetchIdleTaskForRequest_(request, b);
+ mTasksCS.unlock();
+ return ret;
+ }
+
+ sead::TypedBitFlag<Flag, u8> mFlags;
+ u8 mListIndex = 0;
+ ManagedTask* mTask = nullptr;
+ sead::CriticalSection mTasksCS;
+ sead::CriticalSection mCS2;
+ Event mNewFreeTaskEvent;
+ Event mEvent2;
+ sead::SafeArray<sead::OffsetList<ManagedTask>, 2> mFreeTaskLists;
+ sead::Buffer<ManagedTask*> mTasks;
+};
+KSYS_CHECK_SIZE_NX150(TaskMgr, 0x158);
+
+} // namespace ksys::util