diff --git a/include/functions.h b/include/functions.h index cfa7f4fad6..3c20bca11c 100644 --- a/include/functions.h +++ b/include/functions.h @@ -194,16 +194,7 @@ s32 func_80086D40(f64 param_1); f64 func_80086D6C(f64 param_1); s32 func_80086D8C(f32 param_1); s32 func_80086DAC(f64 param_1); -void* SystemArena_Malloc(size_t size); -void* SystemArena_MallocR(size_t size); -void* SystemArena_Realloc(void* oldPtr, size_t newSize); -void SystemArena_Free(void* ptr); -void* SystemArena_Calloc(u32 elements, size_t size); -void SystemArena_AnalyzeArena(size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated); -u32 SystemArena_CheckArena(void); -void SystemArena_InitArena(void* start, size_t size); -void SystemArena_Cleanup(void); -u8 SystemArena_IsInitialized(void); + s32 Rand_Next(void); void Rand_Seed(u32 seed); f32 Rand_ZeroOne(void); @@ -212,20 +203,7 @@ void Rand_Seed_Variable(u32* rndNum, u32 seed); u32 Rand_Next_Variable(u32* param_1); f32 Rand_ZeroOne_Variable(u32* param_1); f32 Rand_Centered_Variable(u32* param_1); -void ArenaImpl_LockInit(Arena* heap); -void ArenaImpl_Lock(Arena* heap); -void ArenaImpl_Unlock(Arena* heap); -ArenaNode* ArenaImpl_GetLastBlock(Arena* param_1); -void __osMallocInit(Arena* heap, void* heapBase, size_t heapSize); -void __osMallocAddBlock(Arena* heap, void* start, s32 size); -void __osMallocCleanup(Arena* heap); -u8 __osMallocIsInitalized(Arena* heap); -void* __osMalloc(Arena* heap, size_t size); -void* __osMallocR(Arena* heap, size_t size); -void __osFree(Arena* heap, void* ptr); -void* __osRealloc(Arena* heap, void* oldPtr, size_t newSize); -void __osAnalyzeArena(Arena* heap, size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated); -u32 __osCheckArena(Arena* heap); + void* proutSprintf(void* s, const char* buf, size_t n); s32 vsprintf(char* dst, char* fmt, va_list args); s32 sprintf(char* s, char* fmt, ...); @@ -1769,7 +1747,7 @@ void* ZeldaArena_Realloc(void* oldPtr, size_t newSize); void ZeldaArena_Free(void* param_1); void* ZeldaArena_Calloc(u32 num, size_t size); void ZeldaArena_GetSizes(size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated); -void ZeldaArena_Check(); +s32 ZeldaArena_Check(); void ZeldaArena_Init(void* start, size_t size); void ZeldaArena_Cleanup(); u8 ZeldaArena_IsInitialized(); diff --git a/include/macros.h b/include/macros.h index 7e6104317a..21593c13b6 100644 --- a/include/macros.h +++ b/include/macros.h @@ -2,7 +2,7 @@ #define _MACROS_H_ #include "libc/stdint.h" -#include "convert.h" +#include "ultra64/convert.h" #include "z64.h" #define SCREEN_WIDTH 320 diff --git a/include/os_malloc.h b/include/os_malloc.h new file mode 100644 index 0000000000..6b1cceab5a --- /dev/null +++ b/include/os_malloc.h @@ -0,0 +1,35 @@ +#ifndef OS_MALLOC +#define OS_MALLOC + +#include "PR/ultratypes.h" +#include "ultra64/message.h" +#include "libc/stddef.h" + +typedef struct ArenaNode { + /* 0x0 */ s16 magic; // Should always be 0x7373 + /* 0x2 */ s16 isFree; + /* 0x4 */ size_t size; + /* 0x8 */ struct ArenaNode* next; + /* 0xC */ struct ArenaNode* prev; +} ArenaNode; // size = 0x10 + +typedef struct { + /* 0x00 */ ArenaNode* head; + /* 0x04 */ void* start; + /* 0x08 */ OSMesgQueue lock; + /* 0x20 */ u8 unk20; + /* 0x21 */ u8 isInit; + /* 0x22 */ u8 flag; +} Arena; // size = 0x24 + +void __osMallocInit(Arena* arena, void* heap, size_t size); +void __osMallocCleanup(Arena* arena); +u8 __osMallocIsInitalized(Arena* arena); +void* __osMalloc(Arena* arena, size_t size); +void* __osMallocR(Arena* arena, size_t size); +void __osFree(Arena* arena, void* ptr); +void* __osRealloc(Arena* arena, void* ptr, size_t newSize); +void __osGetSizes(Arena* arena, size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated); +s32 __osCheckArena(Arena* arena); + +#endif diff --git a/include/system_malloc.h b/include/system_malloc.h new file mode 100644 index 0000000000..e92eaf89fd --- /dev/null +++ b/include/system_malloc.h @@ -0,0 +1,20 @@ +#ifndef SYSTEM_MALLOC +#define SYSTEM_MALLOC + +#include "PR/ultratypes.h" +#include "os_malloc.h" + +void* SystemArena_Malloc(size_t size); +void* SystemArena_MallocR(size_t size); +void* SystemArena_Realloc(void* oldPtr, size_t newSize); +void SystemArena_Free(void* ptr); +void* SystemArena_Calloc(u32 elements, size_t size); +void SystemArena_GetSizes(size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated); +u32 SystemArena_CheckArena(void); +void SystemArena_InitArena(void* start, size_t size); +void SystemArena_Cleanup(void); +u8 SystemArena_IsInitialized(void); + +extern Arena gSystemArena; + +#endif diff --git a/include/convert.h b/include/ultra64/convert.h similarity index 94% rename from include/convert.h rename to include/ultra64/convert.h index c453e18e3a..59d8b801c3 100644 --- a/include/convert.h +++ b/include/ultra64/convert.h @@ -1,5 +1,5 @@ -#ifndef _ULTRA64_CONVERT_H_ -#define _ULTRA64_CONVERT_H_ +#ifndef ULTRA64_CONVERT_H +#define ULTRA64_CONVERT_H #include "libc/stdint.h" diff --git a/include/variables.h b/include/variables.h index 6d1fc3ef96..cabe5d09e4 100644 --- a/include/variables.h +++ b/include/variables.h @@ -322,7 +322,6 @@ extern StackEntry sFaultThreadInfo; extern FaultThreadStruct gFaultStruct; extern FaultDrawer sFaultDrawerStruct; // extern UNK_TYPE4 D_8009CD10; -// extern Arena gSystemArena; extern u32 sRandFloat; // extern UNK_TYPE4 sArenaLockMsg; extern OSTask tmp_task; @@ -3271,7 +3270,6 @@ extern s16 D_801F4E7A; // extern UNK_TYPE1 D_801F4F68; // extern UNK_TYPE1 D_801F4F6A; extern LightsBuffer sLightsBuffer; -extern Arena sZeldaArena; // extern UNK_TYPE1 D_801F5130; // extern UNK_TYPE1 D_801F5270; // extern UNK_TYPE1 D_801F528E; diff --git a/include/z64.h b/include/z64.h index 31eec335b7..1aba77e7af 100644 --- a/include/z64.h +++ b/include/z64.h @@ -884,23 +884,6 @@ typedef struct { /* 0x120D8 */ UNK_TYPE1 pad120D8[0x8]; } MessageContext; // size = 0x120E0 -typedef struct ArenaNode { - /* 0x0 */ s16 magic; // Should always be 0x7373 - /* 0x2 */ s16 isFree; - /* 0x4 */ size_t size; - /* 0x8 */ struct ArenaNode* next; - /* 0xC */ struct ArenaNode* prev; -} ArenaNode; // size = 0x10 - -typedef struct { - /* 0x00 */ ArenaNode* head; - /* 0x04 */ void* start; - /* 0x08 */ OSMesgQueue lock; - /* 0x20 */ u8 unk20; - /* 0x21 */ u8 isInit; - /* 0x22 */ u8 flag; -} Arena; // size = 0x24 - typedef struct FaultAddrConvClient { /* 0x0 */ struct FaultAddrConvClient* next; /* 0x4 */ void* (*callback)(void*, void*); diff --git a/spec b/spec index aa2eacaea1..10b3e560e5 100644 --- a/spec +++ b/spec @@ -46,7 +46,6 @@ beginseg include "build/src/boot_O2/system_malloc.o" include "build/src/boot_O2/rand.o" include "build/src/boot_O2/__osMalloc.o" - include "build/data/boot/__osMalloc.bss.o" include "build/src/libultra/rmon/sprintf.o" include "build/src/boot_O2/printutils.o" include "build/src/boot_O2/sleep.o" @@ -491,7 +490,6 @@ beginseg include "build/src/code/z_lights.o" include "build/data/code/z_lights.bss.o" include "build/src/code/z_malloc.o" - include "build/data/code/z_malloc.bss.o" include "build/src/code/z_map_disp.o" include "build/data/code/z_map_disp.data.o" include "build/data/code/z_map_disp.bss.o" diff --git a/src/boot_O2/__osMalloc.c b/src/boot_O2/__osMalloc.c index c74c34866b..24fa6d39ec 100644 --- a/src/boot_O2/__osMalloc.c +++ b/src/boot_O2/__osMalloc.c @@ -1,4 +1,8 @@ -#include "global.h" +#include "os_malloc.h" +#include "libc/stdbool.h" +#include "libc/stdint.h" +#include "macros.h" +#include "functions.h" #define FILL_ALLOCBLOCK (1 << 0) #define FILL_FREEBLOCK (1 << 1) @@ -13,9 +17,9 @@ #define BLOCK_FREE_MAGIC (0xEF) #define BLOCK_FREE_MAGIC_32 (0xEFEFEFEF) -extern OSMesg sArenaLockMsg[1]; +OSMesg sArenaLockMsg[1]; -#pragma GLOBAL_ASM("asm/non_matchings/boot/__osMalloc/D_80099110.s") +void __osMallocAddHeap(Arena* arena, void* heap, size_t size); void ArenaImpl_LockInit(Arena* arena) { osCreateMesgQueue(&arena->lock, sArenaLockMsg, ARRAY_COUNT(sArenaLockMsg)); @@ -45,111 +49,184 @@ ArenaNode* ArenaImpl_GetLastBlock(Arena* arena) { return last; } -void __osMallocInit(Arena* arena, void* start, size_t size) { - bzero(arena, sizeof(*arena)); +/** + * Initializes \p arena to manage the memory region \p heap. + * + * @param arena The Arena to initialize. + * @param heap The memory region to use as heap space. + * @param size The size of the heap. + */ +void __osMallocInit(Arena* arena, void* heap, size_t size) { + bzero(arena, sizeof(Arena)); + ArenaImpl_LockInit(arena); - __osMallocAddBlock(arena, start, size); - arena->isInit = 1; + + __osMallocAddHeap(arena, heap, size); + arena->isInit = true; } -void __osMallocAddBlock(Arena* arena, void* start, s32 size) { - s32 diff; - s32 size2; +// Original name: __osMallocAddBlock +void __osMallocAddHeap(Arena* arena, void* heap, size_t size) { + ptrdiff_t diff; + s32 alignedSize; ArenaNode* firstNode; ArenaNode* lastNode; - if (start != NULL) { - firstNode = (ArenaNode*)ALIGN16((u32)start); - diff = (s32)firstNode - (s32)start; - size2 = (size - diff) & ~0xF; + if (heap == NULL) { + return; + } - if (size2 > (s32)sizeof(ArenaNode)) { - firstNode->next = NULL; - firstNode->prev = NULL; - firstNode->size = size2 - sizeof(ArenaNode); - firstNode->isFree = 1; - firstNode->magic = NODE_MAGIC; - ArenaImpl_Lock(arena); - lastNode = ArenaImpl_GetLastBlock(arena); - if (lastNode == NULL) { - arena->head = firstNode; - arena->start = start; - } else { - firstNode->prev = lastNode; - lastNode->next = firstNode; - } - ArenaImpl_Unlock(arena); + firstNode = (ArenaNode*)ALIGN16((uintptr_t)heap); + diff = (uintptr_t)firstNode - (uintptr_t)heap; + alignedSize = ((s32)size - diff) & ~0xF; + + // If the size of the heap is smaller than sizeof(ArenaNode), then the initialization will silently fail + if (alignedSize > (s32)sizeof(ArenaNode)) { + firstNode->next = NULL; + firstNode->prev = NULL; + firstNode->size = alignedSize - sizeof(ArenaNode); + firstNode->isFree = true; + firstNode->magic = NODE_MAGIC; + + ArenaImpl_Lock(arena); + + lastNode = ArenaImpl_GetLastBlock(arena); + + // Checks if there's already a block + if (lastNode == NULL) { + arena->head = firstNode; + arena->start = heap; + } else { + // Chain the existing block with the new one + firstNode->prev = lastNode; + lastNode->next = firstNode; } + + ArenaImpl_Unlock(arena); } } +/** + * Clears the whole \p arena, invalidating every allocated pointer to it. + * + * @param arena The Arena to clear. + */ void __osMallocCleanup(Arena* arena) { - bzero(arena, sizeof(*arena)); + bzero(arena, sizeof(Arena)); } +/** + * Returns whether or not the \p arena has been initialized. + * + * @param arena The Arena to check. + * @return u8 `true` if the \p arena has been initialized. `false` otherwise. + */ u8 __osMallocIsInitalized(Arena* arena) { return arena->isInit; } +/** + * Allocates at least \p size bytes of memory using the given \p arena. + * The block of memory will be allocated at the start of the first sufficiently large free block. + * + * - If there's not enough space in the given \p arena, this function will fail, returning `NULL`. + * - If \p size is zero, then an empty region of memory is returned. + * + * To avoid memory leaks, the returned pointer should be eventually deallocated using either `__osFree` or + * `__osRealloc`. + * + * @param[in, out] arena The specific Arena to be used for the allocation. + * @param[in] size The size in bytes that will be allocated. + * @return void* On success, the allocated area of the \p arena memory. Otherwise, `NULL`. + */ void* __osMalloc(Arena* arena, size_t size) { ArenaNode* iter; ArenaNode* newNode; - void* alloc; - u32 blockSize; - alloc = NULL; + void* alloc = NULL; size = ALIGN16(size); + ArenaImpl_Lock(arena); + + // Start iterating from the head of the arena. iter = arena->head; + // Iterate over the arena looking for a big enough space of memory. while (iter != NULL) { if (iter->isFree && iter->size >= size) { - ArenaNode* next; - blockSize = ALIGN16(size) + sizeof(ArenaNode); + size_t blockSize = ALIGN16(size) + sizeof(ArenaNode); + + // If the block is larger than the requested size, then split it and just use the required size of the + // current block. if (blockSize < iter->size) { - newNode = (ArenaNode*)((u32)iter + blockSize); + ArenaNode* next; + + newNode = (ArenaNode*)((uintptr_t)iter + blockSize); newNode->next = iter->next; newNode->prev = iter; newNode->size = iter->size - blockSize; - newNode->isFree = 1; + newNode->isFree = true; newNode->magic = NODE_MAGIC; iter->next = newNode; iter->size = size; + next = newNode->next; - if (next) { + if (next != NULL) { next->prev = newNode; } } - iter->isFree = 0; - alloc = (void*)((u32)iter + sizeof(ArenaNode)); + iter->isFree = false; + alloc = (void*)((uintptr_t)iter + sizeof(ArenaNode)); break; } iter = iter->next; } + ArenaImpl_Unlock(arena); return alloc; } +/** + * Allocates at least \p size bytes of memory using the given \p arena. + * Unlike __osMalloc, the block of memory will be allocated from the end of the \p arena. + * + * - If there's not enough space in the given \p arena, this function will fail, returning `NULL`. + * - If \p size is zero, then an empty region of memory is returned. + * + * To avoid memory leaks, the returned pointer should be eventually deallocated using `__osFree` or `__osRealloc`. + * + * @param[in, out] arena The specific Arena to be used for the allocation. + * @param[in] size The size in bytes that will be allocated. + * @return void* On success, the allocated area of the \p arena memory. Otherwise, `NULL`. + */ void* __osMallocR(Arena* arena, size_t size) { ArenaNode* iter; ArenaNode* newNode; - u32 blockSize; + size_t blockSize; void* alloc = NULL; size = ALIGN16(size); + ArenaImpl_Lock(arena); + + // Start iterating from the last block of the arena. iter = ArenaImpl_GetLastBlock(arena); + // Iterate in reverse the arena looking for a big enough space of memory. while (iter != NULL) { if (iter->isFree && iter->size >= size) { - ArenaNode* next; blockSize = ALIGN16(size) + sizeof(ArenaNode); + + // If the block is larger than the requested size, then split it and just use the required size of the + // current block. if (blockSize < iter->size) { - newNode = (ArenaNode*)((u32)iter + (iter->size - size)); + ArenaNode* next; + + newNode = (ArenaNode*)((uintptr_t)iter + (iter->size - size)); newNode->next = iter->next; newNode->prev = iter; newNode->size = size; @@ -157,69 +234,171 @@ void* __osMallocR(Arena* arena, size_t size) { iter->next = newNode; iter->size -= blockSize; + next = newNode->next; - if (next) { + if (next != NULL) { next->prev = newNode; } iter = newNode; } - iter->isFree = 0; - alloc = (void*)((u32)iter + sizeof(ArenaNode)); + iter->isFree = false; + alloc = (void*)((uintptr_t)iter + sizeof(ArenaNode)); break; } iter = iter->prev; } + ArenaImpl_Unlock(arena); return alloc; } +/** + * Deallocates the pointer \p ptr previously allocated by `__osMalloc`, `__osMallocR` or `__osRealloc`. + * If \p ptr is `NULL` or it has been already been freed, then this function does nothing. + * + * - The behaviour is undefined if \p ptr is not a memory region returned by one of the cited allocating + * functions. + * - The behaviour is undefined if \p ptr doesn't correspond to the given \p arena. + * - Any access to the freed pointer is undefined behaviour. + * + * @param[in, out] arena The specific Arena to be used for the allocation. + * @param[in, out] ptr The allocated memory block to deallocate. + */ void __osFree(Arena* arena, void* ptr) { ArenaNode* node; ArenaNode* next; ArenaNode* prev; - ArenaNode* newNext; ArenaImpl_Lock(arena); + node = (ArenaNode*)((uintptr_t)ptr - sizeof(ArenaNode)); - if (ptr == NULL || (node->magic != NODE_MAGIC) || node->isFree) { - goto end; - } + if (ptr != NULL && node->magic == NODE_MAGIC && !node->isFree) { + next = node->next; + prev = node->prev; + node->isFree = true; - next = node->next; - prev = node->prev; - node->isFree = true; + // Checks if the next node is contiguous to the current node and if it isn't currently allocated. Then merge the + // two nodes into one. + if ((uintptr_t)next == (uintptr_t)node + sizeof(ArenaNode) + node->size && next->isFree) { + ArenaNode* newNext = next->next; - newNext = next; - if ((uintptr_t)next == (uintptr_t)node + sizeof(ArenaNode) + node->size && next->isFree) { - newNext = next->next; - if (newNext != NULL) { - newNext->prev = node; + if (newNext != NULL) { + newNext->prev = node; + } + + node->size += next->size + sizeof(ArenaNode); + + node->next = newNext; + next = newNext; } - node->size += next->size + sizeof(ArenaNode); + // Checks if the previous node is contiguous to the current node and if it isn't currently allocated. Then merge + // the two nodes into one. + if (prev != NULL && prev->isFree && (uintptr_t)node == (uintptr_t)prev + sizeof(ArenaNode) + prev->size) { + if (next != NULL) { + next->prev = prev; + } - node->next = newNext; - next = newNext; - } - - if (prev != NULL && prev->isFree && (uintptr_t)node == (uintptr_t)prev + sizeof(ArenaNode) + prev->size) { - if (next) { - next->prev = prev; + prev->next = next; + prev->size += node->size + sizeof(ArenaNode); } - prev->next = next; - prev->size += node->size + sizeof(ArenaNode); } -end: ArenaImpl_Unlock(arena); } -#pragma GLOBAL_ASM("asm/non_matchings/boot/__osMalloc/__osRealloc.s") +/** + * Reallocates the pointer \p ptr. + * \p ptr must be either a pointer previously allocated by `__osMalloc`, `__osMallocR` or `__osRealloc` and + * not freed yet, or a `NULL` pointer. + * + * - If \p ptr is `NULL` a new pointer is allocated. See `__osMalloc` for more details. + * - If \p newSize is 0, then the given pointer is freed and `NULL` is returned. See `__osFree` for more details. + * - If \p newSize is bigger than the currently allocated allocated pointer, then the area of memory is expanded to a + * size big enough to fit the requested size. + * + * - The behaviour is undefined if \p ptr is not a memory region returned by one of the cited allocating + * functions. + * - The behaviour is undefined if \p ptr doesn't correspond to the given \p arena. + * - If the pointer is freed, then any access to the original freed pointer is undefined behaviour. + * + * @param[in, out] arena The specific Arena to be used for the allocation. + * @param[in, out] ptr The allocated memory block to deallocate. + * @param[in] newSize The new requested size. + * @return void* On success, the pointer to the reallocated area of memory. On failure, `NULL` is returned, + * and the original parameter \p ptr remains valid. + */ +void* __osRealloc(Arena* arena, void* ptr, size_t newSize) { + ArenaImpl_Lock(arena); -void __osAnalyzeArena(Arena* arena, size_t* outMaxFree, size_t* outFree, size_t* outAlloc) { + (void)"__osRealloc(%08x, %d)\n"; + + if (ptr == NULL) { + // if the `ptr` is NULL, then allocate a new pointer with the specified size + // if newSize is 0, then __osMalloc would return a NULL pointer + ptr = __osMalloc(arena, newSize); + } else if (newSize == 0) { + // if the requested size is zero, then free the pointer + __osFree(arena, ptr); + ptr = NULL; + } else { + size_t diff; + void* newPtr; + // Gets the start of the ArenaNode pointer embedded + ArenaNode* node = (void*)((uintptr_t)ptr - sizeof(ArenaNode)); + + newSize = ALIGN16(newSize); + + // Only reallocate the memory if the new size isn't smaller than the actual node size + if ((newSize != node->size) && (node->size < newSize)) { + ArenaNode* next = node->next; + + diff = newSize - node->size; + // Checks if the next node is contiguous to the current allocated node and it has enough space to fit the + // new requested size + if (((uintptr_t)next == (uintptr_t)node + node->size + sizeof(ArenaNode)) && (next->isFree) && + (next->size >= diff)) { + ArenaNode* next2 = next->next; + + next->size = (next->size - diff); + if (next2 != NULL) { + // Update the previous element of the linked list + next2->prev = (void*)((uintptr_t)next + diff); + } + + next2 = (void*)((uintptr_t)next + diff); + node->next = next2; + node->size = newSize; + __osMemcpy(next2, next, sizeof(ArenaNode)); + } else { + // Create a new pointer and manually copy the data from the old pointer to the new one + newPtr = __osMalloc(arena, newSize); + if (newPtr != NULL) { + bcopy(newPtr, ptr, node->size); + __osFree(arena, ptr); + } + ptr = newPtr; + } + } + } + + ArenaImpl_Unlock(arena); + + return ptr; +} + +/** + * Gets the size of the largest free block, the total free space and the total allocated space. + * + * @param[in, out] arena The Arena which will be used to get the values from. + * @param[out] outMaxFree The size of the largest free block. + * @param[out] outFree The total free space. + * @param[out] outAlloc The total allocated space. + */ +void __osGetSizes(Arena* arena, size_t* outMaxFree, size_t* outFree, size_t* outAlloc) { ArenaNode* iter; ArenaImpl_Lock(arena); @@ -245,4 +424,35 @@ void __osAnalyzeArena(Arena* arena, size_t* outMaxFree, size_t* outFree, size_t* ArenaImpl_Unlock(arena); } -#pragma GLOBAL_ASM("asm/non_matchings/boot/__osMalloc/__osCheckArena.s") +/** + * Checks the validity of every node of the \p arena. + * + * @param arena The Arena to check. + * @return s32 0 if every pointer is valid. 1 otherwise. + */ +s32 __osCheckArena(Arena* arena) { + ArenaNode* iter; + s32 err = 0; + + ArenaImpl_Lock(arena); + + // "Checking the contents of the arena..." + (void)"アリーナの内容をチェックしています... (%08x)\n"; + + for (iter = arena->head; iter != NULL; iter = iter->next) { + if (iter->magic != NODE_MAGIC) { + // "Oops!!" + (void)"おおっと!! (%08x %08x)\n"; + + err = 1; + break; + } + } + + // "The arena still looks good" + (void)"アリーナはまだ、いけそうです\n"; + + ArenaImpl_Unlock(arena); + + return err; +} diff --git a/src/boot_O2/boot_800862E0.c b/src/boot_O2/boot_800862E0.c index ecba8c5f54..1055dfe1b8 100644 --- a/src/boot_O2/boot_800862E0.c +++ b/src/boot_O2/boot_800862E0.c @@ -1,4 +1,5 @@ #include "global.h" +#include "os_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/boot/boot_800862E0/SystemArena_MallocMin1.s") diff --git a/src/boot_O2/loadfragment.c b/src/boot_O2/loadfragment.c index 4589cd3590..968fb464ab 100644 --- a/src/boot_O2/loadfragment.c +++ b/src/boot_O2/loadfragment.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/boot/loadfragment/Load_Relocate.s") diff --git a/src/boot_O2/loadfragment2.c b/src/boot_O2/loadfragment2.c index 5c884be962..c324b80d5c 100644 --- a/src/boot_O2/loadfragment2.c +++ b/src/boot_O2/loadfragment2.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" UNK_TYPE4 D_80096C30 = 2; diff --git a/src/boot_O2/system_malloc.c b/src/boot_O2/system_malloc.c index ad2bb63458..56608166cb 100644 --- a/src/boot_O2/system_malloc.c +++ b/src/boot_O2/system_malloc.c @@ -1,4 +1,5 @@ #include "global.h" +#include "os_malloc.h" Arena gSystemArena; @@ -29,8 +30,8 @@ void* SystemArena_Calloc(u32 elements, size_t size) { return ptr; } -void SystemArena_AnalyzeArena(size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated) { - __osAnalyzeArena(&gSystemArena, maxFreeBlock, bytesFree, bytesAllocated); +void SystemArena_GetSizes(size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated) { + __osGetSizes(&gSystemArena, maxFreeBlock, bytesFree, bytesAllocated); } u32 SystemArena_CheckArena(void) { diff --git a/src/code/game.c b/src/code/game.c index e431fafdaf..2713be2990 100644 --- a/src/code/game.c +++ b/src/code/game.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" s32 gFramerateDivisor = 1; f32 gFramerateDivisorF = 1.0f; @@ -174,7 +175,7 @@ void GameState_Realloc(GameState* gameState, size_t size) { alloc = &gameState->alloc; THA_Dt(&gameState->heap); GameAlloc_Free(alloc, heapStart); - SystemArena_AnalyzeArena(&systemMaxFree, &bytesFree, &bytesAllocated); + SystemArena_GetSizes(&systemMaxFree, &bytesFree, &bytesAllocated); size = ((systemMaxFree - (sizeof(ArenaNode))) < size) ? (0) : (size); if (size == 0) { size = systemMaxFree - (sizeof(ArenaNode)); diff --git a/src/code/gamealloc.c b/src/code/gamealloc.c index 541f9125b0..6067ad91c4 100644 --- a/src/code/gamealloc.c +++ b/src/code/gamealloc.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" void GameAlloc_Log(GameAlloc* this) { GameAllocEntry* iter; diff --git a/src/code/graph.c b/src/code/graph.c index e09cfedc4b..8059d1f63a 100644 --- a/src/code/graph.c +++ b/src/code/graph.c @@ -1,5 +1,6 @@ #include "prevent_bss_reordering.h" #include "global.h" +#include "system_malloc.h" #include "overlays/gamestates/ovl_daytelop/z_daytelop.h" #include "overlays/gamestates/ovl_file_choose/z_file_choose.h" #include "overlays/gamestates/ovl_opening/z_opening.h" diff --git a/src/code/listalloc.c b/src/code/listalloc.c index da294a1091..33f9989ba1 100644 --- a/src/code/listalloc.c +++ b/src/code/listalloc.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" ListAlloc* ListAlloc_Init(ListAlloc* this) { this->prev = NULL; diff --git a/src/code/speed_meter.c b/src/code/speed_meter.c index b8b0299eba..9f04de110c 100644 --- a/src/code/speed_meter.c +++ b/src/code/speed_meter.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/code/speed_meter/func_80177390.s") diff --git a/src/code/sys_cmpdma.c b/src/code/sys_cmpdma.c index c670645fc2..2533c44f5e 100644 --- a/src/code/sys_cmpdma.c +++ b/src/code/sys_cmpdma.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/code/sys_cmpdma/func_80178750.s") diff --git a/src/code/sys_flashrom.c b/src/code/sys_flashrom.c index 1431e7a666..8b6c2fa5cc 100644 --- a/src/code/sys_flashrom.c +++ b/src/code/sys_flashrom.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/code/sys_flashrom/func_801857C0.s") diff --git a/src/code/z_DLF.c b/src/code/z_DLF.c index 688a5af159..4c57aca014 100644 --- a/src/code/z_DLF.c +++ b/src/code/z_DLF.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/code/z_DLF/Overlay_LoadGameState.s") diff --git a/src/code/z_debug.c b/src/code/z_debug.c index 924a2ad305..46649a4ce1 100644 --- a/src/code/z_debug.c +++ b/src/code/z_debug.c @@ -1,11 +1,12 @@ #include "global.h" +#include "system_malloc.h" GameInfo* gGameInfo; void GameInfo_Init(void) { s32 i; - gGameInfo = (GameInfo*)SystemArena_Malloc(sizeof(GameInfo)); + gGameInfo = SystemArena_Malloc(sizeof(GameInfo)); if (1) {} gGameInfo->unk_00 = 0; gGameInfo->unk_01 = 0; diff --git a/src/code/z_fbdemo.c b/src/code/z_fbdemo.c index c2da6f9cef..3d33399e58 100644 --- a/src/code/z_fbdemo.c +++ b/src/code/z_fbdemo.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/code/z_fbdemo/func_80163DC0.s") diff --git a/src/code/z_malloc.c b/src/code/z_malloc.c index 8d0bba44ac..781f4310e8 100644 --- a/src/code/z_malloc.c +++ b/src/code/z_malloc.c @@ -1,4 +1,7 @@ #include "global.h" +#include "os_malloc.h" + +Arena sZeldaArena; void* ZeldaArena_Malloc(size_t size) { void* ptr = __osMalloc(&sZeldaArena, size); @@ -34,11 +37,11 @@ void* ZeldaArena_Calloc(u32 num, size_t size) { } void ZeldaArena_GetSizes(size_t* outMaxFree, size_t* outFree, size_t* outAlloc) { - __osAnalyzeArena(&sZeldaArena, outMaxFree, outFree, outAlloc); + __osGetSizes(&sZeldaArena, outMaxFree, outFree, outAlloc); } -void ZeldaArena_Check() { - __osCheckArena(&sZeldaArena); +s32 ZeldaArena_Check() { + return __osCheckArena(&sZeldaArena); } void ZeldaArena_Init(void* start, size_t size) { diff --git a/src/code/z_vismono.c b/src/code/z_vismono.c index 4e02a0af2c..6c0d1ef223 100644 --- a/src/code/z_vismono.c +++ b/src/code/z_vismono.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/code/z_vismono/func_801418B0.s") diff --git a/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c b/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c index 296d6e429f..697ea58e8f 100644 --- a/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c +++ b/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c @@ -5,6 +5,7 @@ */ #include "z_eff_dust.h" +#include "system_malloc.h" #define FLAGS 0x00000030 diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 7466934fb9..69ca079a9b 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -204,7 +204,7 @@ 0x80086E20:("SystemArena_Realloc",), 0x80086E50:("SystemArena_Free",), 0x80086E78:("SystemArena_Calloc",), - 0x80086ECC:("SystemArena_AnalyzeArena",), + 0x80086ECC:("SystemArena_GetSizes",), 0x80086F04:("SystemArena_CheckArena",), 0x80086F28:("SystemArena_InitArena",), 0x80086F58:("SystemArena_Cleanup",), @@ -222,14 +222,14 @@ 0x800871B4:("ArenaImpl_Unlock",), 0x800871DC:("ArenaImpl_GetLastBlock",), 0x8008720C:("__osMallocInit",), - 0x8008725C:("__osMallocAddBlock",), + 0x8008725C:("__osMallocAddHeap",), 0x800872FC:("__osMallocCleanup",), 0x8008731C:("__osMallocIsInitalized",), 0x80087324:("__osMalloc",), 0x80087408:("__osMallocR",), 0x800874EC:("__osFree",), 0x800875E4:("__osRealloc",), - 0x80087714:("__osAnalyzeArena",), + 0x80087714:("__osGetSizes",), 0x800877C4:("__osCheckArena",), 0x80087830:("proutSprintf",), 0x80087854:("vsprintf",), diff --git a/tools/sizes/boot_functions.csv b/tools/sizes/boot_functions.csv index 46e57b75c8..3685e3fa9c 100644 --- a/tools/sizes/boot_functions.csv +++ b/tools/sizes/boot_functions.csv @@ -201,7 +201,7 @@ asm/non_matchings/boot/system_malloc/SystemArena_MallocR.s,SystemArena_MallocR,0 asm/non_matchings/boot/system_malloc/SystemArena_Realloc.s,SystemArena_Realloc,0x80086E20,0xC asm/non_matchings/boot/system_malloc/SystemArena_Free.s,SystemArena_Free,0x80086E50,0xA asm/non_matchings/boot/system_malloc/SystemArena_Calloc.s,SystemArena_Calloc,0x80086E78,0x15 -asm/non_matchings/boot/system_malloc/SystemArena_AnalyzeArena.s,SystemArena_AnalyzeArena,0x80086ECC,0xE +asm/non_matchings/boot/system_malloc/SystemArena_GetSizes.s,SystemArena_GetSizes,0x80086ECC,0xE asm/non_matchings/boot/system_malloc/SystemArena_CheckArena.s,SystemArena_CheckArena,0x80086F04,0x9 asm/non_matchings/boot/system_malloc/SystemArena_InitArena.s,SystemArena_InitArena,0x80086F28,0xC asm/non_matchings/boot/system_malloc/SystemArena_Cleanup.s,SystemArena_Cleanup,0x80086F58,0x9 @@ -219,14 +219,14 @@ asm/non_matchings/boot/__osMalloc/ArenaImpl_Lock.s,ArenaImpl_Lock,0x8008718C,0xA asm/non_matchings/boot/__osMalloc/ArenaImpl_Unlock.s,ArenaImpl_Unlock,0x800871B4,0xA asm/non_matchings/boot/__osMalloc/ArenaImpl_GetLastBlock.s,ArenaImpl_GetLastBlock,0x800871DC,0xC asm/non_matchings/boot/__osMalloc/__osMallocInit.s,__osMallocInit,0x8008720C,0x14 -asm/non_matchings/boot/__osMalloc/__osMallocAddBlock.s,__osMallocAddBlock,0x8008725C,0x28 +asm/non_matchings/boot/__osMalloc/__osMallocAddHeap.s,__osMallocAddHeap,0x8008725C,0x28 asm/non_matchings/boot/__osMalloc/__osMallocCleanup.s,__osMallocCleanup,0x800872FC,0x8 asm/non_matchings/boot/__osMalloc/__osMallocIsInitalized.s,__osMallocIsInitalized,0x8008731C,0x2 asm/non_matchings/boot/__osMalloc/__osMalloc.s,__osMalloc,0x80087324,0x39 asm/non_matchings/boot/__osMalloc/__osMallocR.s,__osMallocR,0x80087408,0x39 asm/non_matchings/boot/__osMalloc/__osFree.s,__osFree,0x800874EC,0x3E asm/non_matchings/boot/__osMalloc/__osRealloc.s,__osRealloc,0x800875E4,0x4C -asm/non_matchings/boot/__osMalloc/__osAnalyzeArena.s,__osAnalyzeArena,0x80087714,0x2C +asm/non_matchings/boot/__osMalloc/__osGetSizes.s,__osGetSizes,0x80087714,0x2C asm/non_matchings/boot/__osMalloc/__osCheckArena.s,__osCheckArena,0x800877C4,0x1B asm/non_matchings/boot/sprintf/proutSprintf.s,proutSprintf,0x80087830,0x9 asm/non_matchings/boot/sprintf/vsprintf.s,vsprintf,0x80087854,0x14