summaryrefslogtreecommitdiff
path: root/arm9/src/heap.c
diff options
context:
space:
mode:
Diffstat (limited to 'arm9/src/heap.c')
-rw-r--r--arm9/src/heap.c363
1 files changed, 184 insertions, 179 deletions
diff --git a/arm9/src/heap.c b/arm9/src/heap.c
index 7f35fdcc..842fd33a 100644
--- a/arm9/src/heap.c
+++ b/arm9/src/heap.c
@@ -1,31 +1,45 @@
#include "heap.h"
#include "error_message_reset.h"
#include "unk_02031734.h"
+#include "NNS_FND_expheap.h"
+#include "NNS_FND_allocator.h"
+struct HeapInfo
+{
+ NNSFndHeapHandle *heapHandles;
+ NNSFndHeapHandle *parentHeapHandles;
+ void **subHeapRawPtrs;
+ u16 *numMemBlocks;
+ u8 *heapIdxs;
+ u16 totalNumHeaps;
+ u16 nTemplates;
+ u16 maxHeaps;
+ u16 unallocatedHeapId;
+};
+
+typedef struct MemoryBlock
+{
+ u8 filler_00[12];
+ u32 heapId:8;
+ u32 filler_0D:24;
+} MemoryBlock;
-extern void *NNS_FndCreateExpHeapEx(void *param0, u32 param1, u32 param2);
-extern void *NNS_FndAllocFromExpHeapEx(void *param0, u32 param1, s32 param2);
-extern void NNS_FndDestroyExpHeap();
-extern void NNS_FndFreeToExpHeap(void *ptr1, void *ptr2);
-extern u32 NNS_FndGetTotalFreeSizeForExpHeap(void *param0);
-extern void NNS_FndInitAllocatorForExpHeap(u32 param0, void *param1, u32 param2);
-extern u32 NNS_FndGetSizeForMBlockExpHeap(void *param0);
-extern void NNS_FndResizeForMBlockExpHeap(void *ptr1, void *ptr2, u32 param2);
-
-
-struct UnkStruct_020166C8 UNK_021C4D28;
-
+struct HeapInfo sHeapInfo;
-THUMB_FUNC void FUN_020166C8(u32 *param0, u32 param1, u32 param2, u32 pre_size)
+THUMB_FUNC void InitHeapSystem(const struct HeapParam *templates, u32 nTemplates, u32 totalNumHeaps, u32 pre_size)
{
- u32 unk_size = param1 + 24;
+ void * ptr;
+ u32 unk_size, i;
- if (param2 < unk_size)
+ unk_size = nTemplates + 24;
+
+ if (totalNumHeaps < unk_size)
{
- param2 = unk_size;
+ totalNumHeaps = unk_size;
}
if (pre_size != 0)
{
+ // force align
while (pre_size % 4 != 0)
{
pre_size++;
@@ -34,207 +48,196 @@ THUMB_FUNC void FUN_020166C8(u32 *param0, u32 param1, u32 param2, u32 pre_size)
OS_AllocFromArenaLo(OS_ARENA_MAIN, pre_size, 4);
}
- u32 r7 = param2 * 2;
-
- void *ptr = OS_AllocFromArenaLo(OS_ARENA_MAIN, (unk_size * 3 + 1) * sizeof(u32) + r7 + param2, 4);
- UNK_021C4D28.unk00 = ptr;
- ptr += (unk_size + 1) * 4;
- UNK_021C4D28.unk04 = ptr;
- ptr += unk_size * 4;
- UNK_021C4D28.unk08 = ptr;
- ptr += unk_size * 4;
- UNK_021C4D28.unk0c = ptr;
- ptr += r7;
- UNK_021C4D28.unk10 = ptr;
- UNK_021C4D28.unk14 = (u16)param2;
- UNK_021C4D28.unk16 = (u16)param1;
-
- r7 = 0;
- UNK_021C4D28.unk1a = (u16)unk_size;
- UNK_021C4D28.unk18 = (u16)unk_size;
-
- while (r7 < param1)
+ sHeapInfo.heapHandles = (NNSFndHeapHandle*) OS_AllocFromArenaLo(
+ OS_ARENA_MAIN,
+ (unk_size + 1) * sizeof(NNSFndHeapHandle)
+ + unk_size * sizeof(NNSFndHeapHandle)
+ + unk_size * sizeof(void *)
+ + totalNumHeaps * sizeof(u16)
+ + totalNumHeaps,
+ 4
+ );
+ sHeapInfo.parentHeapHandles = sHeapInfo.heapHandles + (unk_size + 1);
+ sHeapInfo.subHeapRawPtrs = (void **)(sHeapInfo.parentHeapHandles + unk_size);
+ sHeapInfo.numMemBlocks = (u16 *)(sHeapInfo.subHeapRawPtrs + unk_size);
+ sHeapInfo.heapIdxs = (u8 *)(sHeapInfo.numMemBlocks + totalNumHeaps);
+ sHeapInfo.totalNumHeaps = (u16)totalNumHeaps;
+ sHeapInfo.nTemplates = (u16)nTemplates;
+
+ sHeapInfo.unallocatedHeapId = (u16)unk_size;
+ sHeapInfo.maxHeaps = (u16)unk_size;
+
+ for (i = 0; i < nTemplates; i++)
{
- void *ptr;
- if (param0[1] == 0 || param0[1] != 2)
+ switch (templates[i].arena)
{
- ptr = OS_AllocFromArenaLo(OS_ARENA_MAIN, param0[0], 4);
- }
- else
- {
- ptr = OS_AllocFromArenaHi(OS_ARENA_MAINEX, param0[0], 4);
+ case OS_ARENA_MAIN:
+ default:
+ ptr = OS_AllocFromArenaLo(OS_ARENA_MAIN, templates[i].size, 4);
+ break;
+ case OS_ARENA_MAINEX:
+ ptr = OS_AllocFromArenaHi(OS_ARENA_MAINEX, templates[i].size, 4);
+ break;
}
- if (ptr != 0)
+ if (ptr != NULL)
{
- UNK_021C4D28.unk00[r7] = NNS_FndCreateExpHeapEx(ptr, param0[0], 0);
- UNK_021C4D28.unk10[r7] = (u8)r7;
+ sHeapInfo.heapHandles[i] = NNS_FndCreateExpHeap(ptr, templates[i].size);
+ sHeapInfo.heapIdxs[i] = (u8)i;
}
else
{
- GF_AssertFail();
+ GF_ASSERT(0);
}
-
- param0 += 2;
- r7++;
}
- while (param1 < unk_size + 1)
+ for (i = nTemplates; i < unk_size + 1; i++)
{
- UNK_021C4D28.unk00[param1] = 0;
- UNK_021C4D28.unk10[param1] = (u8)UNK_021C4D28.unk1a;
-
- param1++;
+ sHeapInfo.heapHandles[i] = NULL;
+ sHeapInfo.heapIdxs[i] = (u8)sHeapInfo.unallocatedHeapId;
}
- while (param1 < param2)
+ while (i < totalNumHeaps)
{
- UNK_021C4D28.unk10[param1] = (u8)UNK_021C4D28.unk1a;
+ sHeapInfo.heapIdxs[i] = (u8)sHeapInfo.unallocatedHeapId;
- param1++;
+ i++;
}
- for (param1 = 0; param1 < param2; param1++)
+ for (i = 0; i < totalNumHeaps; i++)
{
- UNK_021C4D28.unk0c[param1] = 0;
+ sHeapInfo.numMemBlocks[i] = 0;
}
}
-THUMB_FUNC s32 FUN_020167F4()
+THUMB_FUNC s32 FindFirstAvailableHeapHandle()
{
- s32 i = UNK_021C4D28.unk16;
- s32 j = UNK_021C4D28.unk18;
+ s32 i;
- if (i < j)
+ for (i = sHeapInfo.nTemplates; i < sHeapInfo.maxHeaps; i++)
{
- void **ptr = UNK_021C4D28.unk00 + i;
- do
- {
- if (*ptr == 0)
- {
- return i;
- }
- i++;
- ptr++;
- } while (i < j);
+ if (sHeapInfo.heapHandles[i] == NULL)
+ return i;
}
return -1;
}
-THUMB_FUNC u32 FUN_0201681C(u32 param0, u32 param1, u32 param2)
+THUMB_FUNC BOOL CreateHeap(u32 parent, u32 child, u32 size)
{
- return FUN_02016834(param0, param1, param2, 4);
+ return CreateHeapInternal(parent, child, size, 4);
}
-THUMB_FUNC u32 FUN_02016828(u32 param0, u32 param1, u32 param2)
+THUMB_FUNC BOOL CreateHeapAtEnd(u32 parent, u32 child, u32 size)
{
- return FUN_02016834(param0, param1, param2, -4);
+ return CreateHeapInternal(parent, child, size, -4);
}
-THUMB_FUNC u32 FUN_02016834(u32 param0, u32 param1, u32 param2, s32 param3)
+THUMB_FUNC BOOL CreateHeapInternal(u32 parent, u32 child, u32 size, s32 alignment)
{
GF_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
- u8 *ptr = UNK_021C4D28.unk10;
- if (UNK_021C4D28.unk1a == ptr[param1])
+ u8 *ptr = sHeapInfo.heapIdxs;
+ if (sHeapInfo.unallocatedHeapId == ptr[child])
{
- void *ptr2 = UNK_021C4D28.unk00[ptr[param0]];
- if (ptr2 != 0)
+ NNSFndHeapHandle parentHeap = sHeapInfo.heapHandles[ptr[parent]];
+ if (parentHeap != NULL)
{
- void *ptr3 = NNS_FndAllocFromExpHeapEx(ptr2, param2, param3);
- if (ptr3 != 0)
+ void *newHeapAddr = NNS_FndAllocFromExpHeapEx(parentHeap, size, alignment);
+ if (newHeapAddr != NULL)
{
- param3 = FUN_020167F4();
- if (param3 >= 0)
+ s32 i = FindFirstAvailableHeapHandle();
+ if (i >= 0)
{
- UNK_021C4D28.unk00[param3] = NNS_FndCreateExpHeapEx(ptr3, param2, 0);
+ sHeapInfo.heapHandles[i] = NNS_FndCreateExpHeap(newHeapAddr, size);
- if (UNK_021C4D28.unk00[param3] != 0)
+ if (sHeapInfo.heapHandles[i] != NULL)
{
- UNK_021C4D28.unk04[param3] = ptr2;
- UNK_021C4D28.unk08[param3] = ptr3;
- UNK_021C4D28.unk10[param1] = (u8)param3;
+ sHeapInfo.parentHeapHandles[i] = parentHeap;
+ sHeapInfo.subHeapRawPtrs[i] = newHeapAddr;
+ sHeapInfo.heapIdxs[child] = (u8)i;
- return 1;
+ return TRUE;
}
else
{
- GF_AssertFail();
+ GF_ASSERT(0);
}
}
else
{
- GF_AssertFail();
+ GF_ASSERT(0);
}
}
else
{
- GF_AssertFail();
+ GF_ASSERT(0);
}
}
else
{
- GF_AssertFail();
+ GF_ASSERT(0);
}
}
else
{
- GF_AssertFail();
+ GF_ASSERT(0);
}
- return 0;
+ return FALSE;
}
-THUMB_FUNC void FUN_020168D0(u32 heap_id)
+THUMB_FUNC void DestroyHeap(u32 heap_id)
{
- GF_ASSERT (OS_GetProcMode() != OS_PROCMODE_IRQ);
+ GF_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
+
+ NNSFndHeapHandle handle = sHeapInfo.heapHandles[sHeapInfo.heapIdxs[heap_id]];
- if (UNK_021C4D28.unk00[UNK_021C4D28.unk10[heap_id]] != 0)
+ if (handle != NULL)
{
- NNS_FndDestroyExpHeap();
+ NNS_FndDestroyExpHeap(handle);
- u8 index = UNK_021C4D28.unk10[heap_id];
- void *ptr1 = UNK_021C4D28.unk04[index];
- void *ptr2 = UNK_021C4D28.unk08[index];
- if (ptr1 != 0 && ptr2 != 0)
+ u8 index = sHeapInfo.heapIdxs[heap_id];
+ NNSFndHeapHandle parentHeap = sHeapInfo.parentHeapHandles[index];
+ void *childRaw = sHeapInfo.subHeapRawPtrs[index];
+ if (parentHeap != NULL && childRaw != NULL)
{
- NNS_FndFreeToExpHeap(ptr1, ptr2);
+ NNS_FndFreeToExpHeap(parentHeap, childRaw);
}
else
{
- GF_AssertFail();
+ GF_ASSERT(0);
}
- UNK_021C4D28.unk00[UNK_021C4D28.unk10[heap_id]] = 0;
- UNK_021C4D28.unk04[UNK_021C4D28.unk10[heap_id]] = 0;
- UNK_021C4D28.unk08[UNK_021C4D28.unk10[heap_id]] = 0;
+ sHeapInfo.heapHandles[sHeapInfo.heapIdxs[heap_id]] = NULL;
+ sHeapInfo.parentHeapHandles[sHeapInfo.heapIdxs[heap_id]] = NULL;
+ sHeapInfo.subHeapRawPtrs[sHeapInfo.heapIdxs[heap_id]] = NULL;
- UNK_021C4D28.unk10[heap_id] = (u8)UNK_021C4D28.unk1a;
+ sHeapInfo.heapIdxs[heap_id] = (u8)sHeapInfo.unallocatedHeapId;
}
}
-THUMB_FUNC u32 *FUN_02016944(void *param0, u32 param1, s32 param2, u32 param3)
+THUMB_FUNC void *AllocFromHeapInternal(NNSFndHeapHandle heap, u32 size, s32 alignment, u32 heap_id)
{
- GF_ASSERT(param0);
+ GF_ASSERT(heap);
OSIntrMode intr_mode = OS_DisableInterrupts();
- param1 += 16;
- u32 *ptr = (u32 *)NNS_FndAllocFromExpHeapEx(param0, param1, param2);
+ size += sizeof(MemoryBlock);
+ void *ptr = NNS_FndAllocFromExpHeapEx(heap, size, alignment);
OS_RestoreInterrupts(intr_mode);
- if (ptr != 0)
+ if (ptr != NULL)
{
- ptr[3] = (ptr[3] & ~0xff) | (param3 & 0xff);
+ ((MemoryBlock *)ptr)->heapId = heap_id;
- ptr += 4;
+ ptr += sizeof(MemoryBlock);
}
return ptr;
}
-THUMB_FUNC void FUN_02016988()
+THUMB_FUNC void AllocFail()
{
if (FUN_02031810() != 0)
{
@@ -244,19 +247,19 @@ THUMB_FUNC void FUN_02016988()
void *AllocFromHeap(u32 heap_id, u32 size)
{
- void *ptr = 0;
- if (heap_id < UNK_021C4D28.unk14)
+ void *ptr = NULL;
+ if (heap_id < sHeapInfo.totalNumHeaps)
{
- u8 index = UNK_021C4D28.unk10[heap_id];
- ptr = FUN_02016944(UNK_021C4D28.unk00[index], size, 4, heap_id);
+ u8 index = sHeapInfo.heapIdxs[heap_id];
+ ptr = AllocFromHeapInternal(sHeapInfo.heapHandles[index], size, 4, heap_id);
}
- if (ptr != 0)
+ if (ptr != NULL)
{
- UNK_021C4D28.unk0c[heap_id]++;
+ sHeapInfo.numMemBlocks[heap_id]++;
}
else
{
- FUN_02016988();
+ AllocFail();
}
return ptr;
@@ -264,20 +267,20 @@ void *AllocFromHeap(u32 heap_id, u32 size)
void *AllocFromHeapAtEnd(u32 heap_id, u32 size)
{
- void *ptr = 0;
- if (heap_id < UNK_021C4D28.unk14)
+ void *ptr = NULL;
+ if (heap_id < sHeapInfo.totalNumHeaps)
{
- u8 index = UNK_021C4D28.unk10[heap_id];
- ptr = FUN_02016944(UNK_021C4D28.unk00[index], size, -4, heap_id);
+ u8 index = sHeapInfo.heapIdxs[heap_id];
+ ptr = AllocFromHeapInternal(sHeapInfo.heapHandles[index], size, -4, heap_id);
}
- if (ptr != 0)
+ if (ptr != NULL)
{
- UNK_021C4D28.unk0c[heap_id]++;
+ sHeapInfo.numMemBlocks[heap_id]++;
}
else
{
- FUN_02016988();
+ AllocFail();
}
return ptr;
@@ -285,97 +288,99 @@ void *AllocFromHeapAtEnd(u32 heap_id, u32 size)
void FreeToHeap(void *ptr)
{
- u8 heap_id = (u8)((u32 *)ptr)[-1];
+ ptr -= sizeof(MemoryBlock);
+ u32 heap_id = ((MemoryBlock *)ptr)->heapId;
- if ((u16)heap_id < UNK_021C4D28.unk14)
+ if (heap_id < sHeapInfo.totalNumHeaps)
{
- u8 index = UNK_021C4D28.unk10[heap_id];
- void *ptr2 = UNK_021C4D28.unk00[index];
- GF_ASSERT(ptr2);
+ u8 index = sHeapInfo.heapIdxs[heap_id];
+ NNSFndHeapHandle heap = sHeapInfo.heapHandles[index];
+ GF_ASSERT(heap != NULL);
- if (UNK_021C4D28.unk0c[heap_id] == 0)
+ if (sHeapInfo.numMemBlocks[heap_id] == 0)
{
- FUN_02016B90(heap_id);
+ GF_heap_c_dummy_return_true(heap_id);
}
- GF_ASSERT(UNK_021C4D28.unk0c[heap_id]);
+ GF_ASSERT(sHeapInfo.numMemBlocks[heap_id] != 0);
- UNK_021C4D28.unk0c[heap_id]--;
+ sHeapInfo.numMemBlocks[heap_id]--;
OSIntrMode intr_mode = OS_DisableInterrupts();
- NNS_FndFreeToExpHeap(ptr2, ptr - 16);
+ NNS_FndFreeToExpHeap(heap, ptr);
OS_RestoreInterrupts(intr_mode);
return;
}
- GF_AssertFail();
+ GF_ASSERT(0);
}
-void FreeToHeapExplicit(u32 param0, void *param1)
+void FreeToHeapExplicit(u32 heap_id, void *ptr)
{
- GF_ASSERT (OS_GetProcMode() != OS_PROCMODE_IRQ);
+ GF_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
- if (param0 < UNK_021C4D28.unk14)
+ if (heap_id < sHeapInfo.totalNumHeaps)
{
- u8 index = UNK_021C4D28.unk10[param0];
- void *ptr = UNK_021C4D28.unk00[index];
- GF_ASSERT (ptr );
+ u8 index = sHeapInfo.heapIdxs[heap_id];
+ NNSFndHeapHandle heap = sHeapInfo.heapHandles[index];
+ GF_ASSERT( heap != NULL );
- u8 heap_id = (u8)((u32 *)param1)[-1];
- GF_ASSERT (heap_id == param0);
+ ptr -= sizeof(MemoryBlock);
+ GF_ASSERT(((MemoryBlock *)ptr)->heapId == heap_id);
- NNS_FndFreeToExpHeap(ptr, param1 - 16);
- GF_ASSERT (UNK_021C4D28.unk0c[param0]);
+ NNS_FndFreeToExpHeap(heap, ptr);
+ GF_ASSERT(sHeapInfo.numMemBlocks[heap_id] != 0);
- UNK_021C4D28.unk0c[param0]--;
+ sHeapInfo.numMemBlocks[heap_id]--;
return;
}
- GF_AssertFail();
+ GF_ASSERT(0);
}
-THUMB_FUNC u32 FUN_02016AF8(u32 param0)
+THUMB_FUNC u32 GF_ExpHeap_FndGetTotalFreeSize(u32 heap_id)
{
- if (param0 < UNK_021C4D28.unk14)
+ if (heap_id < sHeapInfo.totalNumHeaps)
{
- u8 index = UNK_021C4D28.unk10[param0];
- return NNS_FndGetTotalFreeSizeForExpHeap(UNK_021C4D28.unk00[index]);
+ u8 index = sHeapInfo.heapIdxs[heap_id];
+ return NNS_FndGetTotalFreeSizeForExpHeap(sHeapInfo.heapHandles[index]);
}
- GF_AssertFail();
+ GF_ASSERT(0);
return 0;
}
-THUMB_FUNC void FUN_02016B20(u32 param0, u32 param1, u32 param2)
+THUMB_FUNC void GF_ExpHeap_FndInitAllocator(NNSFndAllocator * pAllocator, u32 heap_id, int alignment)
{
- if (param1 < UNK_021C4D28.unk14)
+ if (heap_id < sHeapInfo.totalNumHeaps)
{
- u8 index = UNK_021C4D28.unk10[param1];
- NNS_FndInitAllocatorForExpHeap(param0, UNK_021C4D28.unk00[index], param2);
+ u8 index = sHeapInfo.heapIdxs[heap_id];
+ NNS_FndInitAllocatorForExpHeap(pAllocator, sHeapInfo.heapHandles[index], alignment);
return;
}
- GF_AssertFail();
+ GF_ASSERT(0);
}
-THUMB_FUNC void FUN_02016B44(void *ptr, u32 param1)
+THUMB_FUNC void ReallocFromHeap(void *ptr, u32 newSize)
{
- GF_ASSERT (OS_GetProcMode() != OS_PROCMODE_IRQ);
+ GF_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
- param1 += 16;
- if (NNS_FndGetSizeForMBlockExpHeap(ptr - 16) >= param1)
+ newSize += sizeof(MemoryBlock);
+ ptr -= sizeof(MemoryBlock);
+ if (NNS_FndGetSizeForMBlockExpHeap(ptr) >= newSize)
{
- u8 heap_id = (u8)((u32 *)ptr)[-1];
+ u32 heap_id = ((MemoryBlock *)ptr)->heapId;
- u8 index = UNK_021C4D28.unk10[heap_id];
+ u8 index = sHeapInfo.heapIdxs[heap_id];
- NNS_FndResizeForMBlockExpHeap(UNK_021C4D28.unk00[index], ptr - 16, param1);
+ NNS_FndResizeForMBlockExpHeap(sHeapInfo.heapHandles[index], ptr, newSize);
return;
}
- GF_AssertFail();
+ GF_ASSERT(0);
}
-THUMB_FUNC u32 FUN_02016B90(u32 param0)
+THUMB_FUNC BOOL GF_heap_c_dummy_return_true(u32 heap_id)
{
-#pragma unused(param0)
- return 1;
+#pragma unused(heap_id)
+ return TRUE;
}