refactors in JKRThread

This commit is contained in:
SwareJonge 2023-11-03 18:08:54 +01:00
parent 3353a2348e
commit 4e512a29f8
2 changed files with 243 additions and 186 deletions

View File

@ -10,38 +10,40 @@
struct JKRThread;
struct JKRThreadName_ {
struct JKRThreadName_
{
s32 id;
char* name;
char *name;
};
typedef void (*JKRThreadSwitch_PreCallback)(OSThread* current, OSThread* next);
typedef void (*JKRThreadSwitch_PostCallback)(OSThread* current, OSThread* next);
typedef void (*JKRThreadSwitch_PreCallback)(OSThread *current, OSThread *next);
typedef void (*JKRThreadSwitch_PostCallback)(OSThread *current, OSThread *next);
class JKRThreadSwitch {
class JKRThreadSwitch
{
public:
JKRThreadSwitch(JKRHeap*);
virtual void draw(JKRThreadName_* param_1, JUTConsole* param_2);
virtual void draw(JKRThreadName_* param_1);
JKRThreadSwitch(JKRHeap *);
virtual void draw(JKRThreadName_ *param_1, JUTConsole *param_2);
virtual void draw(JKRThreadName_ *param_1);
virtual ~JKRThreadSwitch();
static JKRThreadSwitch* createManager(JKRHeap* heap);
static JKRThreadSwitch *createManager(JKRHeap *heap);
JKRThread* enter(JKRThread* param_1, int param_2);
static void callback(OSThread* param_1, OSThread* param_2);
JKRThread *enter(JKRThread *param_1, int param_2);
static void callback(OSThread *param_1, OSThread *param_2);
static u32 getTotalCount() { return sTotalCount; }
private:
static JKRThreadSwitch* sManager;
static JKRThreadSwitch *sManager;
static u32 sTotalCount;
static u32 sTotalStart;
static JKRThreadSwitch_PreCallback mUserPreCallback;
static JKRThreadSwitch_PostCallback mUserPostCallback;
private:
/* 0x00 */ // vtable
/* 0x04 */ JKRHeap* mHeap;
/* 0x00 */ // vtable
/* 0x04 */ JKRHeap *mHeap;
/* 0x08 */ bool mSetNextHeap;
/* 0x09 */ u8 field_0x9[3];
/* 0x0C */ u32 field_0xC;
@ -104,7 +106,7 @@ struct JKRThread : public JKRDisposer
void setCommon_mesgQueue(JKRHeap *, int);
BOOL setCommon_heapSpecified(JKRHeap *, u32, int);
static void *start(void *);
static JSUList<JKRThread>& getList() { return (JSUList<JKRThread>&)sThreadList; }
static JSUList<JKRThread> &getList() { return (JSUList<JKRThread> &)sThreadList; }
// unused/inlined:
static JKRThread *searchThread(OSThread *);
@ -131,7 +133,7 @@ struct JKRThread : public JKRDisposer
mCurrentHeap = curHeap;
*/
mCurrentHeap = heap ? heap : JKRGetCurrentHeap();
mCurrentHeap = heap ? heap : JKRGetCurrentHeap();
}
static JSUList<JKRThread> sThreadList;
@ -156,18 +158,18 @@ struct JKRThread : public JKRDisposer
*/
struct JKRTask : public JKRThread
{
typedef void (*RequestCallback)(void*);
/**
* @fabricated
* @size{0xC}
*/
struct Message {
RequestCallback _00;
void* _04;
void* _08;
};
typedef void (*RequestCallback)(void *);
/**
* @fabricated
* @size{0xC}
*/
struct Request
{
RequestCallback mCb;
void *mArg;
void *mMsg;
};
JKRTask(int, int, u32); // unused/inlined
@ -176,10 +178,10 @@ struct JKRTask : public JKRThread
bool request(RequestCallback, void *, void *);
static JKRTask *create(int, int, unsigned long, JKRHeap *);
static JKRTask *create(int, int, u32, JKRHeap *);
// unused/inlined:
Message* searchBlank();
Request *searchBlank();
void requestJam(RequestCallback, void *, void *);
void cancelAll();
void createTaskEndMessageQueue(int, JKRHeap *);
@ -187,7 +189,8 @@ struct JKRTask : public JKRThread
void waitQueueMessageBlock(OSMessageQueue *, int *);
void waitQueueMessage(OSMessageQueue *, int *);
OSMessage waitMessageBlock() {
OSMessage waitMessageBlock()
{
OSMessage msg;
OSReceiveMessage(&mMessageQueue, &msg, OS_MESSAGE_BLOCK);
return msg;
@ -196,10 +199,10 @@ struct JKRTask : public JKRThread
static void destroy(JKRTask *);
// u32 _78; // _78
JSULink<JKRTask> _7C; // _7C
Message *_8C; // _8C - ptr to array with elements of size 0xc
u32 _90; // _90 - element count of _8C
OSMessageQueue *_94; // _94
JSULink<JKRTask> mTaskList; // _7C
Request *mRequest; // _8C - ptr to request array
u32 mRequestCnt; // _90 - amount of requests
OSMessageQueue *_94; // _94
static JSUList<JKRTask> sTaskList;
static u8 sEndMesgQueue[32]; // Unused

View File

@ -8,8 +8,9 @@
#include "JSystem/JSupport/JSUList.h"
#include "types.h"
extern "C" {
#include <ppcdis.h>
extern "C"
{
#include <ppcdis.h>
}
// this file has some unused strings that need to be generated by ppcdis or fake functions
@ -17,13 +18,15 @@ extern "C" {
JSUList<JKRThread> JKRThread::sThreadList(false);
JSUList<JKRTask> JKRTask::sTaskList;
JKRThreadSwitch* JKRThreadSwitch::sManager;
JKRThreadSwitch *JKRThreadSwitch::sManager;
u32 JKRThreadSwitch::sTotalCount;
//u64 JKRThreadSwitch::sTotalStart; // Unused
// u64 JKRThreadSwitch::sTotalStart; // Unused
JKRThread::JKRThread(u32 stack_size, int message_count, int param_3) : mThreadListLink(this) {
JKRHeap* heap = JKRHeap::findFromRoot(this);
if (heap == nullptr) {
JKRThread::JKRThread(u32 stack_size, int message_count, int param_3) : mThreadListLink(this)
{
JKRHeap *heap = JKRHeap::findFromRoot(this);
if (heap == nullptr)
{
heap = JKRHeap::getSystemHeap();
}
@ -31,9 +34,11 @@ JKRThread::JKRThread(u32 stack_size, int message_count, int param_3) : mThreadLi
setCommon_mesgQueue(mHeap, message_count);
}
JKRThread::JKRThread(JKRHeap* heap, u32 stack_size, int message_count, int param_4)
: mThreadListLink(this) {
if (heap == nullptr) {
JKRThread::JKRThread(JKRHeap *heap, u32 stack_size, int message_count, int param_4)
: mThreadListLink(this)
{
if (heap == nullptr)
{
heap = JKRHeap::getCurrentHeap();
}
@ -41,7 +46,8 @@ JKRThread::JKRThread(JKRHeap* heap, u32 stack_size, int message_count, int param
setCommon_mesgQueue(mHeap, message_count);
}
JKRThread::JKRThread(OSThread* thread, int message_count) : mThreadListLink(this) {
JKRThread::JKRThread(OSThread *thread, int message_count) : mThreadListLink(this)
{
mHeap = NULL;
mThreadRecord = thread;
mStackSize = (u32)thread->stackEnd - (u32)thread->stackBase;
@ -52,52 +58,57 @@ JKRThread::JKRThread(OSThread* thread, int message_count) : mThreadListLink(this
JKRThread::~JKRThread()
{
sThreadList.remove(&mThreadListLink);
if (mHeap != nullptr) {
if (!OSIsThreadTerminated(mThreadRecord)) {
OSDetachThread(mThreadRecord);
OSCancelThread(mThreadRecord);
}
JKRHeap::free(mStackMemory, mHeap);
JKRHeap::free(mThreadRecord, mHeap);
}
JKRHeap::free(mMesgBuffer, nullptr);
sThreadList.remove(&mThreadListLink);
if (mHeap != nullptr)
{
if (!OSIsThreadTerminated(mThreadRecord))
{
OSDetachThread(mThreadRecord);
OSCancelThread(mThreadRecord);
}
JKRHeap::free(mStackMemory, mHeap);
JKRHeap::free(mThreadRecord, mHeap);
}
JKRHeap::free(mMesgBuffer, nullptr);
}
void JKRThread::setCommon_mesgQueue(JKRHeap* heap, int msgCount)
void JKRThread::setCommon_mesgQueue(JKRHeap *heap, int msgCount)
{
#line 128
mMessageCount = msgCount;
mMesgBuffer = (OSMessage*)JKRHeap::alloc(mMessageCount << 2, 0, heap);
mMessageCount = msgCount;
mMesgBuffer = (OSMessage *)JKRHeap::alloc(mMessageCount << 2, 0, heap);
JUT_ASSERT(mMesgBuffer);
OSInitMessageQueue(&mMessageQueue, mMesgBuffer, mMessageCount);
JKRThread::sThreadList.append(&mThreadListLink);
mCurrentHeap = nullptr;
mCurrentHeapError = nullptr;
OSInitMessageQueue(&mMessageQueue, mMesgBuffer, mMessageCount);
JKRThread::sThreadList.append(&mThreadListLink);
mCurrentHeap = nullptr;
mCurrentHeapError = nullptr;
}
BOOL JKRThread::setCommon_heapSpecified(JKRHeap* heap, unsigned long stackSize, int threadPriority)
BOOL JKRThread::setCommon_heapSpecified(JKRHeap *heap, u32 stackSize, int threadPriority)
{
#line 161
mHeap = heap;
mStackSize = stackSize & ~0x1F;
mStackMemory = JKRHeap::alloc(mStackSize, 0x20, mHeap);
mHeap = heap;
mStackSize = stackSize & ~0x1F;
mStackMemory = JKRHeap::alloc(mStackSize, 0x20, mHeap);
JUT_ASSERT(mStackMemory);
#line 167
mThreadRecord = (OSThread*)JKRHeap::alloc(sizeof(OSThread), 0x20, mHeap);
mThreadRecord = (OSThread *)JKRHeap::alloc(sizeof(OSThread), 0x20, mHeap);
JUT_ASSERT(mThreadRecord);
return OSCreateThread(mThreadRecord, &JKRThread::start, this, (void*)((u32)mStackMemory + mStackSize), mStackSize, threadPriority, 1);
return OSCreateThread(mThreadRecord, &JKRThread::start, this, (void *)((u32)mStackMemory + mStackSize), mStackSize, threadPriority, 1);
}
void* JKRThread::start(void* thread) { return static_cast<JKRThread*>(thread)->run(); }
void *JKRThread::start(void *thread) { return static_cast<JKRThread *>(thread)->run(); }
JKRThread* JKRThread::searchThread(OSThread* thread) {
JSUList<JKRThread>& threadList = getList();
JKRThread *JKRThread::searchThread(OSThread *thread)
{
JSUList<JKRThread> &threadList = getList();
JSUListIterator<JKRThread> iterator;
for (iterator = threadList.getFirst(); iterator != threadList.getEnd(); ++iterator) {
if (iterator->getThreadRecord() == thread) {
for (iterator = threadList.getFirst(); iterator != threadList.getEnd(); ++iterator)
{
if (iterator->getThreadRecord() == thread)
{
return iterator.getObject();
}
}
@ -124,11 +135,13 @@ JKRThreadSwitch::JKRThreadSwitch(JKRHeap *param_0)
mSetNextHeap = true;*/
}
JKRThreadSwitch* JKRThreadSwitch::createManager(JKRHeap* heap) {
JKRThreadSwitch *JKRThreadSwitch::createManager(JKRHeap *heap)
{
#line 343
JUT_ASSERT(sManager == 0);
if (!heap) {
if (!heap)
{
heap = JKRGetCurrentHeap();
}
@ -136,16 +149,19 @@ JKRThreadSwitch* JKRThreadSwitch::createManager(JKRHeap* heap) {
return sManager;
}
JKRThread * JKRThreadSwitch::enter(JKRThread * thread, int id) {
if(thread == nullptr) {
JKRThread *JKRThreadSwitch::enter(JKRThread *thread, int id)
{
if (thread == nullptr)
{
return nullptr;
}
else {
JKRThread * nextThread = JKRThread::searchThread(thread->getThreadRecord());
if(nextThread != nullptr)
else
{
JKRThread *nextThread = JKRThread::searchThread(thread->getThreadRecord());
if (nextThread != nullptr)
thread = nextThread;
JKRThread::TLoad * loadInfo = thread->getLoadInfo();
JKRThread::TLoad *loadInfo = thread->getLoadInfo();
loadInfo->clear();
loadInfo->setValid(true);
loadInfo->setId(id);
@ -153,44 +169,58 @@ JKRThread * JKRThreadSwitch::enter(JKRThread * thread, int id) {
return thread;
}
void JKRThreadSwitch::callback(OSThread* current, OSThread* next) {
if (mUserPreCallback) {
void JKRThreadSwitch::callback(OSThread *current, OSThread *next)
{
if (mUserPreCallback)
{
(*mUserPreCallback)(current, next);
}
sTotalCount = sTotalCount + 1;
JKRHeap* next_heap = NULL;
JSUList<JKRThread>& threadList = JKRThread::getList();
JKRHeap *next_heap = NULL;
JSUList<JKRThread> &threadList = JKRThread::getList();
JSUListIterator<JKRThread> iterator;
for (iterator = threadList.getFirst(); iterator != threadList.getEnd(); ++iterator) {
JKRThread* thread = iterator.getObject();
for (iterator = threadList.getFirst(); iterator != threadList.getEnd(); ++iterator)
{
JKRThread *thread = iterator.getObject();
if (thread->getThreadRecord() == current) {
if (thread->getThreadRecord() == current)
{
thread->setCurrentHeap(JKRHeap::getCurrentHeap());
JKRThread::TLoad* loadInfo = thread->getLoadInfo();
if (loadInfo->isValid()) {
JKRThread::TLoad *loadInfo = thread->getLoadInfo();
if (loadInfo->isValid())
{
loadInfo->addCurrentCost();
}
}
if (thread->getThreadRecord() == next) {
JKRThread::TLoad* loadInfo = thread->getLoadInfo();
if (loadInfo->isValid()) {
if (thread->getThreadRecord() == next)
{
JKRThread::TLoad *loadInfo = thread->getLoadInfo();
if (loadInfo->isValid())
{
loadInfo->setCurrentTime();
loadInfo->incCount();
}
if (sManager->mSetNextHeap) {
if (sManager->mSetNextHeap)
{
next_heap = thread->getCurrentHeap();
if (!next_heap) {
if (!next_heap)
{
next_heap = JKRHeap::getCurrentHeap();
} else if (JKRHeap::getRootHeap()->isSubHeap(next_heap)) {
}
else if (JKRHeap::getRootHeap()->isSubHeap(next_heap))
{
continue;
} else {
switch (thread->getCurrentHeapError()) {
}
else
{
switch (thread->getCurrentHeapError())
{
case 0:
#line 508
#line 508
JUT_PANIC("JKRThreadSwitch: currentHeap destroyed.");
break;
case 1:
@ -209,49 +239,61 @@ void JKRThreadSwitch::callback(OSThread* current, OSThread* next) {
}
}
if (next_heap) {
if (next_heap)
{
next_heap->becomeCurrentHeap();
}
if (mUserPostCallback) {
if (mUserPostCallback)
{
(*mUserPostCallback)(current, next);
}
}
void JKRThreadSwitch::draw(JKRThreadName_* thread_name_list, JUTConsole* console) {
const char* print_0 = " total: switch:%3d time:%d(%df)\n";
const char* print_1 = " -------------------------------------\n";
void JKRThreadSwitch::draw(JKRThreadName_ *thread_name_list, JUTConsole *console)
{
const char *print_0 = " total: switch:%3d time:%d(%df)\n";
const char *print_1 = " -------------------------------------\n";
if (!console) {
/*#if DEBUG
OSReport(print_0, getTotalCount(), (int)field_0x18, field_0x10);
OSReport(print_1);
#endif*/
} else {
if (!console)
{
/*#if DEBUG
OSReport(print_0, getTotalCount(), (int)field_0x18, field_0x10);
OSReport(print_1);
#endif*/
}
else
{
console->clear();
console->print_f(print_0, getTotalCount(), (int)field_0x18, field_0x10);
console->print(print_1);
}
JSUList<JKRThread>& threadList = JKRThread::getList();
JSUList<JKRThread> &threadList = JKRThread::getList();
JSUListIterator<JKRThread> iterator;
for (iterator = threadList.getFirst(); iterator != threadList.getEnd(); ++iterator) {
JKRThread* thread = iterator.getObject();
JKRThread::TLoad* loadInfo = thread->getLoadInfo();
for (iterator = threadList.getFirst(); iterator != threadList.getEnd(); ++iterator)
{
JKRThread *thread = iterator.getObject();
JKRThread::TLoad *loadInfo = thread->getLoadInfo();
if (loadInfo->isValid()) {
char* thread_print_name = NULL;
if (thread_name_list) {
JKRThreadName_* thread_name = thread_name_list;
for (; thread_name->name; thread_name++) {
if (thread_name->id == loadInfo->getId()) {
if (loadInfo->isValid())
{
char *thread_print_name = NULL;
if (thread_name_list)
{
JKRThreadName_ *thread_name = thread_name_list;
for (; thread_name->name; thread_name++)
{
if (thread_name->id == loadInfo->getId())
{
thread_print_name = thread_name->name;
break;
}
}
}
if (!thread_print_name) {
if (!thread_print_name)
{
char buffer[16];
sprintf(buffer, "%d", loadInfo->getId());
thread_print_name = buffer;
@ -262,12 +304,15 @@ void JKRThreadSwitch::draw(JKRThreadName_* thread_name_list, JUTConsole* console
u32 cost_int = (u32)(cost_per_0x18 * 100.0f);
u32 cost_float = (u32)(cost_per_0x18 * 1000.0f) % 10;
if (!console) {
/*#if DEBUG
OSReport(" [%10s] switch:%5d cost:%2d.%d%%\n", thread_print_name, switch_count,
cost_int, cost_float);
#endif*/
} else {
if (!console)
{
/*#if DEBUG
OSReport(" [%10s] switch:%5d cost:%2d.%d%%\n", thread_print_name, switch_count,
cost_int, cost_float);
#endif*/
}
else
{
console->print_f(" [%10s] switch:%5d cost:%2d.%d%%\n", thread_print_name,
switch_count, cost_int, cost_float);
}
@ -280,77 +325,86 @@ CW_FORCE_STRINGS(JKRThread_2, "JUTConsole.h", "console != 0", "bufSize > 0", "sE
#endif
JKRTask::JKRTask(int msgCount, int threadPriority, u32 stackSize)
: JKRThread(stackSize, msgCount, threadPriority)
, _7C(this)
, _94(nullptr)
: JKRThread(stackSize, msgCount, threadPriority), mTaskList(this), _94(nullptr)
{
// UNUSED FUNCTION
OSResumeThread(mThreadRecord);
// UNUSED FUNCTION
OSResumeThread(mThreadRecord);
}
JKRTask::~JKRTask() { sTaskList.remove(&_7C); }
JKRTask::~JKRTask() { sTaskList.remove(&mTaskList); }
JKRTask* JKRTask::create(int msgCount, int threadPriority, unsigned long stackSize, JKRHeap* heap)
JKRTask *JKRTask::create(int reqCount, int threadPriority, u32 stackSize, JKRHeap *heap)
{
if (heap == nullptr) {
heap = JKRHeap::sCurrentHeap;
}
JKRTask* task = new (heap, 0) JKRTask(msgCount, threadPriority, stackSize);
if (task == nullptr) {
return nullptr;
}
task->_8C = new (heap, 0) Message[msgCount];
task->_90 = msgCount;
if (task->_8C == nullptr) {
delete task;
return nullptr;
}
for (int i = 0; i < msgCount; i++) {
task->_8C[i]._00 = nullptr;
}
sTaskList.append(&task->_7C);
return task;
if (heap == nullptr)
{
heap = JKRHeap::sCurrentHeap;
}
JKRTask *task = new (heap, 0) JKRTask(reqCount, threadPriority, stackSize);
if (task == nullptr)
{
return nullptr;
}
task->mRequest = new (heap, 0) Request[reqCount];
task->mRequestCnt = reqCount;
if (task->mRequest == nullptr)
{
delete task;
return nullptr;
}
for (int i = 0; i < reqCount; i++)
{
task->mRequest[i].mCb = nullptr;
}
sTaskList.append(&task->mTaskList);
return task;
}
void* JKRTask::run()
void *JKRTask::run()
{
Message* msg;
Request *req;
OSInitFastCast();
while (true) {
msg = (Message *)waitMessageBlock();
if (msg->_00 != nullptr) {
msg->_00(msg->_04);
if (_94 != nullptr) {
OSSendMessage(_94, msg->_08, OS_MESSAGE_NOBLOCK);
}
}
msg->_00 = nullptr;
}
while (true)
{
req = (Request *)waitMessageBlock();
if (req->mCb != nullptr)
{
req->mCb(req->mArg);
if (_94 != nullptr)
{
OSSendMessage(_94, req->mMsg, OS_MESSAGE_NOBLOCK);
}
}
req->mCb = nullptr;
}
}
JKRTask::Message* JKRTask::searchBlank()
JKRTask::Request *JKRTask::searchBlank()
{
// UNUSED FUNCTION
for (int i = 0; i < (int)_90; i++) {
if (_8C[i]._00 == nullptr) {
return _8C + i;
}
}
return nullptr;
// UNUSED FUNCTION
for (int i = 0; i < (int)mRequestCnt; i++)
{
if (mRequest[i].mCb == nullptr)
{
return &mRequest[i];
}
}
return nullptr;
}
bool JKRTask::request(RequestCallback callback, void* p2, void* p3)
bool JKRTask::request(RequestCallback callback, void *arg, void *msg)
{
Message* msg = searchBlank();
if (msg == nullptr) {
return false;
}
msg->_00 = callback;
msg->_04 = p2;
msg->_08 = p3;
bool sendResult = OSSendMessage(&mMessageQueue, msg, OS_MESSAGE_NOBLOCK);
if (!sendResult) {
msg->_00 = nullptr;
}
return sendResult;
Request *req = searchBlank();
if (req == nullptr)
{
return false;
}
req->mCb = callback;
req->mArg = arg;
req->mMsg = msg;
bool sendResult = OSSendMessage(&mMessageQueue, req, OS_MESSAGE_NOBLOCK);
if (!sendResult)
{
req->mCb = nullptr;
}
return sendResult;
}