Files
ac-decomp/src/JSystem/JKernel/JKRAramHeap.cpp
T
Cuyler36 80ef14e480 Add & Link JKernel (#142)
* match and link JKRAram.cpp

* match and link JKRExpHeap

* match and link JKRAramStream.cpp

* match and link JKRFileLoader.cpp

* match and link JKRFileFinder.cpp

* JKernel Dump

* match and link JKRAramArchive.cpp

* match and link JKRDvdArchive.cpp

* match and link JKRCompArchive.cpp

* match but not link JKRDvdAramRipper

* small refactors

* match and link JKRThread.cpp

* fix and link JKRDvdAramStream.cpp

* Formatting fixes

---------

Co-authored-by: SwareJonge <olaf23okken@gmail.com>
2023-11-07 23:34:10 -05:00

170 lines
4.3 KiB
C++

#include "JSystem/JKernel/JKRAram.h"
#include "JSystem/JSystem.h"
#include "dolphin/os.h" /* TODO: OSReport is actually in libforest */
JSUList<JKRAramBlock> JKRAramHeap::sAramList;
JKRAramHeap::JKRAramHeap(u32 baseAddress, u32 size) : JKRDisposer() {
OSInitMutex(&this->mMutex);
this->mHeap = JKRHeap::findFromRoot(this);
this->mSize = ALIGN_PREV(size, 0x20);
this->mHeadAddress = ALIGN_NEXT(baseAddress, 0x20);
this->mTailAddress = this->mHeadAddress + this->mSize;
this->mGroupID = 0xFF;
JKRAramBlock* block = new (this->mHeap, nullptr)
JKRAramBlock(this->mHeadAddress, 0, this->mSize, 0xFF, false);
sAramList.append(&block->mLink);
}
JKRAramHeap::~JKRAramHeap() {
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
it != sAramList.getEnd();) {
delete (it++).getObject();
}
}
JKRAramBlock* JKRAramHeap::alloc(u32 size, JKRAramHeap::EAllocMode mode) {
JKRAramBlock* block;
this->lock();
if (mode == Head) {
block = this->allocFromHead(size);
}
else {
block = this->allocFromTail(size);
}
this->unlock();
return block;
}
/* Code retrieved from Twilight Princess Debug version & matched. Unused in AC.
*/
void JKRAramHeap::free(JKRAramBlock* block) { delete block; }
JKRAramBlock* JKRAramHeap::allocFromHead(u32 size) {
size = ALIGN_NEXT(size, 32);
u32 min_size = 0xFFFFFFFFUL;
JKRAramBlock* block = nullptr;
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
it != sAramList.getEnd(); it++) {
JKRAramBlock* n_block = it.getObject();
if (n_block->mFreeSize >= size && min_size > n_block->mFreeSize) {
min_size = n_block->mFreeSize;
block = n_block;
if (block->mFreeSize == size) {
break;
}
}
}
if (block != nullptr) {
return block->allocHead(size, this->mGroupID, this);
}
return nullptr;
}
JKRAramBlock* JKRAramHeap::allocFromTail(u32 size) {
JKRAramBlock* block = nullptr;
size = ALIGN_NEXT(size, 32);
for (JSUListIterator<JKRAramBlock> it = sAramList.getLast();
it != sAramList.getEnd(); it--) {
JKRAramBlock* n_block = it.getObject();
if (n_block->mFreeSize >= size) {
block = n_block;
break;
}
}
if (block != nullptr) {
return block->allocTail(size, this->mGroupID, this);
}
return nullptr;
}
/* Debug code retrieved from Twilight Princess Debug version */
void JKRAramHeap::dump() {
this->lock();
int total_used = 0;
JREPORT("\nJKRAramHeap dump\n");
JREPORT(" attr address: size gid\n");
for (JSUListIterator<JKRAramBlock> listItr = sAramList.getFirst();
listItr != sAramList.getEnd(); listItr++) {
if (listItr->mSize != 0) {
JREPORTF("%s %08x: %08x %3d\n",
listItr->isTempMemory() ? " temp" : "alloc", listItr->mAddress,
listItr->mSize, listItr->mGroupID);
}
if (listItr->mFreeSize != 0) {
JREPORTF(" free %08x: %08x 0\n", listItr->mAddress + listItr->mSize,
listItr->mFreeSize);
}
total_used += listItr->mSize;
}
JREPORTF("%d / %d bytes (%6.2f%%) used\n", total_used, this->mSize,
(f32)total_used / (f32)this->mSize);
this->unlock();
}
/* Not present in AC, recreated from TP debug. TODO: Check for matching. */
u32 JKRAramHeap::getFreeSize() {
u32 max_free = 0;
this->lock();
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
it != sAramList.getEnd(); it++) {
if (it->mFreeSize > max_free) {
max_free = it->mFreeSize;
}
}
this->unlock();
return max_free;
}
/* Not present in AC, recreated from TP debug. TODO: Check for matching. */
u32 JKRAramHeap::getTotalFreeSize() {
u32 total_free = 0;
this->lock();
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
it != sAramList.getEnd(); it++) {
total_free += it->mFreeSize;
}
this->unlock();
return total_free;
}
/* Not present in AC, recreated from TP debug. TODO: Check for matching. */
u32 JKRAramHeap::getUsedSize(u8 groupID) {
u32 total_used = 0;
this->lock();
if (groupID == ARAM_GROUP_ID_ALL) {
total_used = this->mSize - this->getTotalFreeSize();
}
else {
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
it != sAramList.getEnd(); it++) {
if (groupID == it->mGroupID) {
total_used += it->mSize;
}
}
}
this->unlock();
return total_used;
}