SMG-Decomp
A decompilation of Super Mario Galaxy 1
Loading...
Searching...
No Matches
FunctionAsyncExecutor.cpp
1#include "Game/System/FunctionAsyncExecutor.hpp"
2#include <JSystem/JKernel/JKRUnitHeap.hpp>
3#include "Game/Util.hpp"
4#include <revolution.h>
5
6FunctionAsyncExecInfo::FunctionAsyncExecInfo(MR::FunctorBase *pFuncPtr, int a2, const char *a3) {
7 mFunc = pFuncPtr;
8 mPriority = a2;
9 _8 = a3;
10 _C = 0;
11 OSInitMessageQueue(&mQueue, &mMessage, 1);
12}
13
14FunctionAsyncExecInfo::~FunctionAsyncExecInfo() {
15 delete mFunc;
16}
17
18void FunctionAsyncExecInfo::execute() {
19 OSThread* thread = OSGetCurrentThread();
20 OSPriority prio = OSGetThreadPriority(thread);
21 OSSetThreadPriority(thread, mPriority);
22 (*mFunc)();
23 OSSetThreadPriority(thread, prio);
24}
25
26FunctionAsyncExecutorThread::FunctionAsyncExecutorThread(JKRHeap *pHeap) : OSThreadWrapper(0x10000, 4, 1, pHeap) {
27 mIsSuspended = false;
28 _40 = 0;
29}
30
31s32 FunctionAsyncExecutorThread::run() {
32 __asm {
33 li r3, 4
34 oris r3, r3, 4
35 mtspr 0x392, r3
36 li r3, 5
37 oris r3, r3, 5
38 mtspr 0x393, r3
39 li r3, 6
40 oris r3, r3, 6
41 mtspr 0x394, r3
42 li r3, 7
43 oris r3, r3, 7
44 mtspr 0x395, r3
45 };
46
47 while(1) {
48 mIsSuspended = false;
49 _40 = 0;
50 OSMessage msg;
51 OSReceiveMessage(&mQueue, &msg, OS_MESSAGE_BLOCK);
52 FunctionAsyncExecInfo* info = reinterpret_cast<FunctionAsyncExecInfo*>(msg);
53 _40 = info->_8;
54 mIsSuspended = true;
55 info->execute();
56 OSSendMessage(&info->mQueue, 0, 0);
57 info->_C = 1;
58 }
59}
60
61FunctionAsyncExecutorOnMainThread::FunctionAsyncExecutorOnMainThread(OSThread* pThread) {
62 mThread = pThread;
63 _0 = 0;
64 OSInitMessageQueue(&mQueue, mMsgArray, 0x40);
65}
66
67void FunctionAsyncExecutorOnMainThread::update() {
68 OSMessage msg;
70 if (OSReceiveMessage(&mQueue, &msg, 0)) {
71 _0 = 1;
72 info = (FunctionAsyncExecInfo*)msg;
73 info->mPriority = OSGetThreadPriority(OSGetCurrentThread());
74 info->execute();
75 OSSendMessage(&info->mQueue, 0, 0);
76 info->_C = 1;
77 }
78}
79
80FunctionAsyncExecutor::FunctionAsyncExecutor() {
81 mMainThreadExec = nullptr;
82 _40C = 0;
83 _410 = nullptr;
84 _414 = nullptr;
85
86 for (int i = 0; i < 2; i++) {
87 FunctionAsyncExecutorThread* thread = new FunctionAsyncExecutorThread(MR::getStationedHeapNapa());
88 mThreads[i] = thread;
89 OSResumeThread(thread->mThread);
90 }
91
92 mMainThreadExec = new FunctionAsyncExecutorOnMainThread(OSGetCurrentThread());
93 _410 = JKRUnitHeap::create(0x34, 0x34A8, 4, MR::getCurrentHeap(), false);
94 _414 = JKRExpHeap::create(0x2800, MR::getCurrentHeap(), false);
95}
96
97void FunctionAsyncExecutor::update() {
98 mMainThreadExec->update();
99}
100
101void FunctionAsyncExecutor::start(const MR::FunctorBase &rBase, int priority, const char *pName) {
102 FunctionAsyncExecInfo* info = createAndAddExecInfo(rBase, priority, pName);
103 FunctionAsyncExecutorThread* thread = getSuspendThread();
104 OSSendMessage(&thread->mQueue, info, 0);
105}
106
107bool FunctionAsyncExecutor::startOnMainThread(const MR::FunctorBase &rBase, const char *pName) {
108 FunctionAsyncExecutorOnMainThread* thread = mMainThreadExec;
109 bool isSameThread = OSGetCurrentThread() == thread->mThread;
110
111 if (isSameThread) {
112 rBase();
113 return false;
114 }
115 else {
116 FunctionAsyncExecInfo* info = createAndAddExecInfo(rBase, 0, pName);
117 OSSendMessage(&mMainThreadExec->mQueue, info, 0);
118 return true;
119 }
120}
121
122void FunctionAsyncExecutor::waitForEnd(const char *pName) {
123 OSLockMutex(&MR::MutexHolder<2>::sMutex);
125 FunctionAsyncExecInfo* const* lst = last();
126
127 while (cur != lst && (*cur)->isSame(pName)) {
128 cur++;
129 }
130
131 FunctionAsyncExecInfo* info = *cur;
132 OSUnlockMutex(&MR::MutexHolder<2>::sMutex);
133 OSReceiveMessage(&info->mQueue, &info->mMessage, OS_MESSAGE_BLOCK);
134 OSLockMutex(&MR::MutexHolder<2>::sMutex);
135 cur = (FunctionAsyncExecInfo**)first();
136 lst = last();
137
138 while (cur != lst && *cur != info) {
139 cur++;
140 }
141
142 if (lst - cur - 1 > 0) {
143 while (cur + 1 != last()) {
144 *cur = cur[1];
145 cur++;
146 }
147 }
148
149 _40C--;
150 OSUnlockMutex(&MR::MutexHolder<2>::sMutex);
151 delete info;
152}
153
154/* this matches but on a different compiler version */
155bool FunctionAsyncExecutor::isEnd(const char *pName) const {
156 OSLockMutex(&MR::MutexHolder<2>::sMutex);
157 FunctionAsyncExecInfo* const* cur = first();
158 FunctionAsyncExecInfo* const* lst = last();
159
160 while((cur != lst) && (*cur)->isSame(pName)) {
161 cur++;
162 }
163
164 FunctionAsyncExecInfo* info = *cur;
165 OSUnlockMutex(&MR::MutexHolder<2>::sMutex);
166 return info->_C;
167}
168
169OSThread* FunctionAsyncExecutor::getOSThread(const char *pName) {
170 for (int i = 0; i < 2; i++) {
171 FunctionAsyncExecutorThread* thread = mThreads[i];
172
173 if (thread->mIsSuspended && MR::isEqualString(thread->_40, pName)) {
174 return thread->mThread;
175 }
176 }
177
178 return nullptr;
179}
180
181FunctionAsyncExecInfo* FunctionAsyncExecutor::createAndAddExecInfo(const MR::FunctorBase &rBase, int priority, const char *pName) {
182 MR::FunctorBase* func = rBase.clone(_414);
183 FunctionAsyncExecInfo* info = new(_410, 0) FunctionAsyncExecInfo(func, priority, pName);
184
185 OSLockMutex(&MR::MutexHolder<2>::sMutex);
186 s32 cnt = _40C;
187 _40C = cnt + 1;
188 mHolders[cnt] = info;
189 OSUnlockMutex(&MR::MutexHolder<2>::sMutex);
190 return info;
191}
192
193FunctionAsyncExecutorThread* FunctionAsyncExecutor::getSuspendThread() {
194 for (int i = 0; i < 2; i++) {
195 if (mThreads[i]->mIsSuspended) {
196 return mThreads[i];
197 }
198 }
199
200 return nullptr;
201}
202
203FunctionAsyncExecutorThread::~FunctionAsyncExecutorThread() {
204
205}