From 804c8ea82dfe03df73bf6c1928986187fb7515f0 Mon Sep 17 00:00:00 2001 From: Jcw87 Date: Thu, 19 Oct 2023 05:32:02 -0700 Subject: [PATCH] JASHeapCtrl --- include/JSystem/JAudio/JASHeapCtrl.h | 59 +++++++ include/JSystem/JSupport/JSUList.h | 2 +- src/JSystem/JAudio/JASHeapCtrl.cpp | 229 +++++++++++++++++++++++---- 3 files changed, 258 insertions(+), 32 deletions(-) create mode 100644 include/JSystem/JAudio/JASHeapCtrl.h diff --git a/include/JSystem/JAudio/JASHeapCtrl.h b/include/JSystem/JAudio/JASHeapCtrl.h new file mode 100644 index 00000000..27f9fc80 --- /dev/null +++ b/include/JSystem/JAudio/JASHeapCtrl.h @@ -0,0 +1,59 @@ +#ifndef JASHEAPCTRL_H +#define JASHEAPCTRL_H + +#include "JSystem/JSupport/JSUList.h" +#include "dolphin/os/OSMutex.h" + +namespace JASystem { + namespace Kernel { + class TDisposer { + public: + virtual void onDispose() {} + }; + + class THeap { + public: + enum Type { + Type0, + Type1, + }; + + THeap(TDisposer*); + void initRootHeap(void*, u32, Type); + bool alloc(THeap*, u32); + bool free(); + void insertChild(THeap* param_1, THeap* param_2, void* param_3, u32 param_4, bool param_5); + JASystem::Kernel::THeap* getTailHeap(); + u32 getTailOffset(); + u32 getCurOffset(); + + bool isAllocated() { return mBase; } + + /* 0x00 */ JSUTree mTree; + /* 0x1C */ OSMutex mMutex; + /* 0x34 */ TDisposer* mDisposer; + /* 0x38 */ Type mType; + /* 0x3C */ u8* mBase; + /* 0x40 */ u32 mSize; + /* 0x44 */ THeap* field_0x44; + }; + + class TSolidHeap { + public: + TSolidHeap(); + ~TSolidHeap() {} + int alloc(long param_1); + void freeAll(); + void init(u8* param_1, long param_2); + int getRemain(); + + /* 0x00 */ u32 field_0x0; + /* 0x04 */ int field_0x4; + /* 0x08 */ int field_0x8; + /* 0x0C */ int field_0xc; + /* 0x10 */ int field_0x10; + }; + } +} + +#endif /* JASHEAPCTRL_H */ diff --git a/include/JSystem/JSupport/JSUList.h b/include/JSystem/JSupport/JSUList.h index 6adb0bc7..e117824b 100644 --- a/include/JSystem/JSupport/JSUList.h +++ b/include/JSystem/JSupport/JSUList.h @@ -212,7 +212,7 @@ public: return *this; } - T& operator*() { return *this->getObject(); } + T* operator*() { return this->getObject(); } T* operator->() { return this->getObject(); } diff --git a/src/JSystem/JAudio/JASHeapCtrl.cpp b/src/JSystem/JAudio/JASHeapCtrl.cpp index 5eabaaf1..0682a2ad 100644 --- a/src/JSystem/JAudio/JASHeapCtrl.cpp +++ b/src/JSystem/JAudio/JASHeapCtrl.cpp @@ -3,76 +3,243 @@ // Translation Unit: JASHeapCtrl.cpp // -#include "JASHeapCtrl.h" -#include "dolphin/types.h" +#include "JSystem/JAudio/JASHeapCtrl.h" +#include "JSystem/JUtility/JUTAssert.h" +#include "dolphin/os/OS.h" /* 8027CC14-8027CC88 .text __ct__Q38JASystem6Kernel5THeapFPQ38JASystem6Kernel9TDisposer */ -JASystem::Kernel::THeap::THeap(JASystem::Kernel::TDisposer*) { - /* Nonmatching */ +JASystem::Kernel::THeap::THeap(TDisposer* disposer) : mTree(this) { + mDisposer = disposer; + mType = Type1; + mBase = NULL; + mSize = 0; + field_0x44 = NULL; + OSInitMutex(&mMutex); } /* 8027CC88-8027CD38 .text initRootHeap__Q38JASystem6Kernel5THeapFPvUlQ48JASystem6Kernel5THeap4Type */ -void JASystem::Kernel::THeap::initRootHeap(void*, unsigned long, JASystem::Kernel::THeap::Type) { - /* Nonmatching */ +void JASystem::Kernel::THeap::initRootHeap(void* ptr, u32 size, Type type) { + JUT_ASSERT(92, ! isAllocated()); + OSLockMutex(&mMutex); + mBase = (u8*)OSRoundUpPtr(ptr, 0x20); + field_0x44 = NULL; + mSize = size - (u32(mBase) - u32(ptr)); + mType = type; + OSUnlockMutex(&mMutex); } /* 8027CD38-8027CF68 .text alloc__Q38JASystem6Kernel5THeapFPQ38JASystem6Kernel5THeapUl */ -void JASystem::Kernel::THeap::alloc(JASystem::Kernel::THeap*, unsigned long) { - /* Nonmatching */ +bool JASystem::Kernel::THeap::alloc(THeap* mother, u32 param_2) { + JUT_ASSERT(118, mother != 0); + OSLockMutex(&mMutex); + if (isAllocated()) { + OSReport("[JASHeap::alloc] すでにヒープは確保されています。初期化してからにしてください。\n"); + OSUnlockMutex(&mMutex); + return false; + } + if (!mother->isAllocated()) { + OSUnlockMutex(&mMutex); + return false; + } + param_2 = OSRoundUp32B(param_2); + u32 local_28 = mother->getCurOffset(); + u32 local_2c = mother->getTailOffset(); + if (local_28 + param_2 <= local_2c) { + mother->insertChild(this, mother->getTailHeap(), mother->mBase + local_28, param_2, false); + OSUnlockMutex(&mMutex); + return true; + } + s32 r27 = -1; + u8* r29 = mother->mBase; + bool local_43 = false; + THeap* local_30 = NULL; + void* local_34; + for (JSUTreeIterator it = mother->mTree.getFirstChild(); it != mother->mTree.getEndChild(); it++) { + if (r29 >= mother->mBase + local_2c) { + break; + } + u32 local_3c = u32(it->mBase) - u32(r29); + if (local_3c >= param_2 && local_3c < r27) { + local_30 = *it; + local_34 = r29; + r27 = local_3c; + local_43 = true; + } + u32 r25 = it->mSize; + r29 = (u8*)it->mBase + r25; + } + if (r29 != mother->mBase && r29 < mother->mBase + local_2c) { + u32 local_40 = mother->mBase + mother->mSize - r29; + if (local_40 >= param_2 && local_40 < r27) { + local_30 = NULL; + local_34 = r29; + r27 = local_40; + local_43 = true; + } + } + if (!local_43) { + OSReport("[JASHeap::alloc] マザーメモリが足りないので確保できません。\n"); + OSUnlockMutex(&mMutex); + return false; + } + mother->insertChild(this, local_30, local_34, param_2, false); + OSUnlockMutex(&mMutex); + return true; } /* 8027CF68-8027D088 .text free__Q38JASystem6Kernel5THeapFv */ -void JASystem::Kernel::THeap::free() { - /* Nonmatching */ +bool JASystem::Kernel::THeap::free() { + OSLockMutex(&mMutex); + if (!isAllocated()) { + OSUnlockMutex(&mMutex); + return false; + } + JSUTreeIterator stack_20; + for (JSUTreeIterator it(mTree.getFirstChild()); it != mTree.getEndChild(); it = stack_20) { + stack_20 = it; + stack_20++; + it->free(); + } + JSUTree* parentTree = mTree.getParent(); + if (parentTree) { + THeap* parentHeap = parentTree->getObject(); + if (parentHeap->field_0x44 == this) { + JSUTreeIterator stack_28(mTree.getPrevChild()); + if (stack_28 != mTree.getEndChild()) { + parentHeap->field_0x44 = *stack_28; + } else { + parentHeap->field_0x44 = NULL; + } + } + parentTree->removeChild(&mTree); + } + mBase = NULL; + field_0x44 = NULL; + mSize = 0; + if (mDisposer) { + mDisposer->onDispose(); + } + OSUnlockMutex(&mMutex); + return true; +} + +static void dummy(JASystem::Kernel::TDisposer* disposer) { + OSReport("------------------------------------\n"); + OSReport("level >= 0 && level < 7"); + OSReport("%s Heap %08x [Addr %8x , Max %8x] %c\n"); } /* 8027D088-8027D1FC .text insertChild__Q38JASystem6Kernel5THeapFPQ38JASystem6Kernel5THeapPQ38JASystem6Kernel5THeapPvUlb */ -void JASystem::Kernel::THeap::insertChild(JASystem::Kernel::THeap*, JASystem::Kernel::THeap*, void*, unsigned long, bool) { - /* Nonmatching */ +void JASystem::Kernel::THeap::insertChild(THeap* heap, THeap* next, void* param_3, u32 param_4, bool param_5) { + JUT_ASSERT(537, heap != 0); + JUT_ASSERT(538, next == 0 || &mTree == next->mTree.getParent()); + OSLockMutex(&mMutex); + if (!param_5) { + JSUTreeIterator it; + if (!next) { + it = mTree.getLastChild(); + } else { + it = next->mTree.getPrevChild(); + } + THeap* r24 = it != mTree.getEndChild() ? it.getObject() : NULL; + if (field_0x44 == r24) { + field_0x44 = heap; + } + } + heap->mBase = (u8*)param_3; + heap->mSize = param_4; + heap->field_0x44 = NULL; + heap->mType = mType; + mTree.insertChild(&next->mTree, &heap->mTree); + OSUnlockMutex(&mMutex); } /* 8027D1FC-8027D280 .text getTailHeap__Q38JASystem6Kernel5THeapFv */ -void JASystem::Kernel::THeap::getTailHeap() { - /* Nonmatching */ +JASystem::Kernel::THeap* JASystem::Kernel::THeap::getTailHeap() { + JSUTreeIterator it; + OSLockMutex(&mMutex); + if (!field_0x44) { + it = mTree.getFirstChild(); + } else { + it = field_0x44->mTree.getNextChild(); + } + OSUnlockMutex(&mMutex); + if (it == mTree.getEndChild()) { + return NULL; + } + return it.getObject(); } /* 8027D280-8027D2E8 .text getTailOffset__Q38JASystem6Kernel5THeapFv */ -void JASystem::Kernel::THeap::getTailOffset() { - /* Nonmatching */ +u32 JASystem::Kernel::THeap::getTailOffset() { + OSLockMutex(&mMutex); + THeap* heap = getTailHeap(); + u32 offset = !heap ? mSize : heap->mBase - mBase; + OSUnlockMutex(&mMutex); + return offset; } /* 8027D2E8-8027D354 .text getCurOffset__Q38JASystem6Kernel5THeapFv */ -void JASystem::Kernel::THeap::getCurOffset() { - /* Nonmatching */ +u32 JASystem::Kernel::THeap::getCurOffset() { + OSLockMutex(&mMutex); + u32 offset = !field_0x44 ? 0 : field_0x44->mBase + field_0x44->mSize - mBase; + OSUnlockMutex(&mMutex); + return offset; } /* 8027D354-8027D370 .text __ct__Q38JASystem6Kernel10TSolidHeapFv */ JASystem::Kernel::TSolidHeap::TSolidHeap() { - /* Nonmatching */ + field_0x0 = 0; + field_0x4 = 0; + field_0x8 = 0; + field_0xc = 0; + field_0x10 = 0; } /* 8027D370-8027D40C .text alloc__Q38JASystem6Kernel10TSolidHeapFl */ -void JASystem::Kernel::TSolidHeap::alloc(long) { +int JASystem::Kernel::TSolidHeap::alloc(s32 size) { /* Nonmatching */ + u32 tmp1 = OSRoundUp32B(size); + if (field_0x0 == 0) { + OSReport("[Nas_HeapAlloc] ヒープが取得できません(ヒープ取得元存在せず)。\n"); + return 0; + } + u32 tmp2 = field_0x4; + if (tmp2 + tmp1 <= field_0x0 + field_0x8) { + field_0x4 = tmp2 + tmp1; + } else { + OSReport("[Nas_HeapAlloc] ヒープが取得できません(ヒープの取得元の残りサイズ不足)。\n"); + return 0; + } + field_0xc++; + field_0x10 = tmp2; + return tmp2; } /* 8027D40C-8027D424 .text freeAll__Q38JASystem6Kernel10TSolidHeapFv */ void JASystem::Kernel::TSolidHeap::freeAll() { - /* Nonmatching */ + field_0x4 = field_0x0; + field_0xc = 0; + field_0x10 = 0; } /* 8027D424-8027D4AC .text init__Q38JASystem6Kernel10TSolidHeapFPUcl */ -void JASystem::Kernel::TSolidHeap::init(unsigned char*, long) { - /* Nonmatching */ +void JASystem::Kernel::TSolidHeap::init(u8* param_1, s32 param_2) { + field_0xc = 0; + if (!param_1) { + OSReport("[Nas_HeapInit] アドレス0からヒープを初期化しようとしています。\n"); + field_0x8 = 0; + field_0x4 = 0; + field_0x10 = 0; + } else { + field_0x0 = OSRoundUp32B(param_1); + field_0x4 = field_0x0; + field_0x8 = param_2 - (field_0x0 - u32(param_1)); + field_0x10 = 0; + } } /* 8027D4AC-8027D4C4 .text getRemain__Q38JASystem6Kernel10TSolidHeapFv */ -void JASystem::Kernel::TSolidHeap::getRemain() { - /* Nonmatching */ +int JASystem::Kernel::TSolidHeap::getRemain() { + return field_0x8 - (field_0x4 - field_0x0); } - -/* 8027D4C4-8027D4C8 .text onDispose__Q38JASystem6Kernel9TDisposerFv */ -void JASystem::Kernel::TDisposer::onDispose() { - /* Nonmatching */ -} -