| 1 | #pragma once |
| 2 | |
| 3 | #include "basis/seadTypes.h" |
| 4 | #include "container/seadBuffer.h" |
| 5 | #include "container/seadSafeArray.h" |
| 6 | #include "framework/seadProcessMeterBar.h" |
| 7 | #include "hostio/seadHostIONode.h" |
| 8 | #include "mc/seadCoreInfo.h" |
| 9 | #include "mc/seadJob.h" |
| 10 | #include "prim/seadEnum.h" |
| 11 | #include "prim/seadNamable.h" |
| 12 | #include "thread/seadAtomic.h" |
| 13 | #include "thread/seadEvent.h" |
| 14 | |
| 15 | namespace sead |
| 16 | { |
| 17 | class Heap; |
| 18 | class Worker; |
| 19 | |
| 20 | SEAD_ENUM(SyncType, cNoSync, cCore, cThread) |
| 21 | |
| 22 | class PerfJobQueue |
| 23 | { |
| 24 | public: |
| 25 | void initialize(const char* name, Heap* heap); |
| 26 | void finalize(); |
| 27 | void reset(); |
| 28 | |
| 29 | void measureBeginDeque(); |
| 30 | void measureEndDeque(); |
| 31 | void measureBeginRun(); |
| 32 | void measureEndRun(); |
| 33 | |
| 34 | const Color4f& getBarColor(u32 idx) const; |
| 35 | void attachProcessMeter(); |
| 36 | void detachProcessMeter(); |
| 37 | |
| 38 | private: |
| 39 | Buffer<MultiProcessMeterBar<512>> mBars; |
| 40 | Buffer<u32> mInts; |
| 41 | MultiProcessMeterBar<1> mProcessMeterBar; |
| 42 | }; |
| 43 | |
| 44 | class JobQueueLock |
| 45 | { |
| 46 | public: |
| 47 | void lock() |
| 48 | { |
| 49 | while (mSpinLock.load() == 1) |
| 50 | continue; |
| 51 | while (!mSpinLock.compareExchange(expected: 0, desired: 1)) |
| 52 | continue; |
| 53 | } |
| 54 | |
| 55 | void unlock() |
| 56 | { |
| 57 | std::atomic_thread_fence(m: std::memory_order_seq_cst); |
| 58 | while (!mSpinLock.compareExchange(expected: 1, desired: 0)) |
| 59 | continue; |
| 60 | } |
| 61 | |
| 62 | private: |
| 63 | Atomic<u32> mSpinLock = 0; |
| 64 | }; |
| 65 | |
| 66 | class JobQueue : public hostio::Node, public INamable |
| 67 | { |
| 68 | public: |
| 69 | enum class Status : int |
| 70 | { |
| 71 | _0 = 0, |
| 72 | _1 = 1, |
| 73 | _3 = 3, |
| 74 | _5 = 5, |
| 75 | _6 = 6, |
| 76 | }; |
| 77 | |
| 78 | JobQueue(); |
| 79 | |
| 80 | virtual void begin() {} |
| 81 | virtual bool run(u32 size, u32* finished_jobs, Worker* worker); |
| 82 | void runAll(u32* finished_jobs); |
| 83 | |
| 84 | virtual u32 getNumJobs() const { return 0; } |
| 85 | bool isAllParticipantThrough() const; |
| 86 | |
| 87 | u32 getGranularity(u32 core) { return mGranularity[core]; } |
| 88 | void setGranularity(CoreId core, u32 x); |
| 89 | void setGranularity(u32); |
| 90 | void setCoreMaskAndWaitType(CoreIdMask mask, SyncType type); |
| 91 | |
| 92 | void FINISH(CoreId core); |
| 93 | void wait_AT_WORKER(); |
| 94 | void wait(); |
| 95 | |
| 96 | const char* getDescription() const { return mDescription; } |
| 97 | void setDescription(const char* description) { mDescription = description; } |
| 98 | |
| 99 | void signalFinishEvent() { mFinishEvent.setSignal(); } |
| 100 | void resetFinishEvent() { mFinishEvent.resetSignal(); } |
| 101 | u32 addNumDoneJobs(u32 num) { return mNumDoneJobs.fetchAdd(x: num); } |
| 102 | |
| 103 | protected: |
| 104 | virtual bool isDone_(); |
| 105 | |
| 106 | SyncType mSyncType = SyncType::cNoSync; |
| 107 | JobQueueLock mLock; |
| 108 | CoreIdMask mMask; |
| 109 | Event mFinishEvent{true}; |
| 110 | SafeArray<u32, 3> mGranularity; |
| 111 | SafeArray<u32, 3> mCoreEnabled; |
| 112 | Atomic<u32> mNumDoneJobs = 0; |
| 113 | |
| 114 | Atomic<Status> mStatus = Status::_0; |
| 115 | const char* mDescription = "NoName" ; |
| 116 | |
| 117 | #ifdef SEAD_DEBUG |
| 118 | PerfJobQueue mPerf; |
| 119 | #endif |
| 120 | }; |
| 121 | |
| 122 | class FixedSizeJQ : public JobQueue |
| 123 | { |
| 124 | public: |
| 125 | FixedSizeJQ(); |
| 126 | |
| 127 | #ifdef SEAD_DEBUG |
| 128 | void listenPropertyEvent(const hostio::PropertyEvent* event) override; |
| 129 | void genMessage(hostio::Context* context) override; |
| 130 | #endif |
| 131 | |
| 132 | void begin() override; |
| 133 | bool run(u32 size, u32* finished_jobs, Worker* worker) override; |
| 134 | u32 getNumJobs() const override; |
| 135 | |
| 136 | void initialize(u32 size, Heap* heap); |
| 137 | void finalize(); |
| 138 | |
| 139 | bool enque(Job* job); |
| 140 | bool enqueSafe(Job* job); |
| 141 | Job* deque(); |
| 142 | u32 deque(Job** jobs, u32 count); |
| 143 | bool rewind(); |
| 144 | void clear(); |
| 145 | |
| 146 | bool debug_IsAllJobDone(); |
| 147 | |
| 148 | protected: |
| 149 | Buffer<Job*> mJobs; |
| 150 | u32 mNumJobs; |
| 151 | u32 mNumProcessedJobs; |
| 152 | bool _230; |
| 153 | }; |
| 154 | } // namespace sead |
| 155 | |