mirror of
https://github.com/pret/pokestadium.git
synced 2026-04-26 01:59:28 -05:00
memory tweaks and cleanups
This commit is contained in:
parent
8897a0f22c
commit
1ffe6bda82
|
|
@ -86,8 +86,8 @@ void func_8000D738(struct UnkInputStruct8000D738* arg0) {
|
|||
s32 temp_v0;
|
||||
|
||||
main_pool_push_state('GBEM');
|
||||
D_800AA660 = (void*)main_pool_alloc_node_no_func(0x2210, 0);
|
||||
D_800AA664 = (void*)main_pool_alloc_node_no_func(0x21E0, 0);
|
||||
D_800AA660 = main_pool_alloc(0x2210, 0);
|
||||
D_800AA664 = main_pool_alloc(0x21E0, 0);
|
||||
func_80004454(((u32)((u32)&fragment1_TEXT_START & 0x0FF00000) >> 0x14) - 0x10, &fragment1_ROM_START,
|
||||
&fragment1_ROM_END);
|
||||
temp_v0 = func_800044F4(&D_3BA190, &D_3CB130, 1, 1);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ struct MemoryPool* mem_pool_try_init(u32 size, s32 side) {
|
|||
struct MemoryPool* ret;
|
||||
|
||||
size = ALIGN4(size);
|
||||
block = main_pool_alloc_node_no_func(size, side);
|
||||
block = main_pool_alloc(size, side);
|
||||
if (block != NULL) {
|
||||
ret = mem_pool_init(block, size);
|
||||
}
|
||||
|
|
@ -128,7 +128,7 @@ void* func_80002D10(u32 size, s32 side) {
|
|||
|
||||
size = ALIGN4(size);
|
||||
ptr = 0;
|
||||
block = main_pool_alloc_node_no_func(size, side);
|
||||
block = main_pool_alloc(size, side);
|
||||
if (block != NULL) {
|
||||
ptr = func_80002DA4(block, size);
|
||||
}
|
||||
|
|
|
|||
11
src/memory.h
11
src/memory.h
|
|
@ -48,12 +48,13 @@ struct MemoryPool {
|
|||
/* 0x24 */ struct MemoryBlock freeList;
|
||||
};
|
||||
|
||||
// memory_main.c
|
||||
void main_pool_init(void *start, void *end);
|
||||
void *main_pool_alloc(u32 size, u32 side);
|
||||
void *main_pool_alloc_from_pool(u32 size, u32 side);
|
||||
u32 main_pool_free(void *addr, u32 runBlockFunc);
|
||||
void *main_pool_alloc_node(u32 size, s32 side, s32 arg, void *func);
|
||||
void *main_pool_alloc_node_no_func(u32 size, s32 side);
|
||||
u32 main_pool_try_free(struct MainPoolBlock *addr);
|
||||
void *main_pool_alloc_with_func(u32 size, s32 side, s32 arg, void *func);
|
||||
void *main_pool_alloc(u32 size, s32 side);
|
||||
u32 main_pool_try_free(void *addr);
|
||||
void *main_pool_realloc(void *addr, size_t size);
|
||||
u32 main_pool_get_available(void);
|
||||
u32 main_pool_push_state(u32 arg);
|
||||
|
|
@ -63,7 +64,7 @@ void main_pool_set_func(void *block, s32 arg, void *func);
|
|||
size_t main_pool_get_block_dist(struct MainPoolBlock *block);
|
||||
struct MainPool *main_pool_get_pool(void);
|
||||
|
||||
// 3640.s
|
||||
// memory.c
|
||||
struct MemoryPool *mem_pool_try_init(u32 size, s32 side);
|
||||
struct MainPool* mem_pool_init(struct MainPool *pool, s32 size);
|
||||
void *mem_pool_alloc(struct MainPool *node, s32 size);
|
||||
|
|
|
|||
|
|
@ -19,13 +19,13 @@ void main_pool_init(void* start, void* end) {
|
|||
sMemPool.listHeadL->prev = NULL;
|
||||
sMemPool.listHeadL->next = NULL;
|
||||
sMemPool.listHeadL->func = NULL;
|
||||
sMemPool.listHeadL->arg = 0;
|
||||
sMemPool.listHeadL->arg = '\0';
|
||||
|
||||
sMemPool.listHeadR = sMemPool.end;
|
||||
sMemPool.listHeadR->prev = NULL;
|
||||
sMemPool.listHeadR->next = NULL;
|
||||
sMemPool.listHeadL->func = NULL;
|
||||
sMemPool.listHeadL->arg = 0;
|
||||
sMemPool.listHeadL->arg = '\0';
|
||||
|
||||
osCreateMesgQueue(&sMemPool.queue, sMemPool.msgs, ARRAY_COUNT(sMemPool.msgs));
|
||||
osSendMesg(&sMemPool.queue, NULL, OS_MESG_NOBLOCK);
|
||||
|
|
@ -36,30 +36,34 @@ void main_pool_init(void* start, void* end) {
|
|||
* specified side of the pool (MEMORY_POOL_LEFT or MEMORY_POOL_RIGHT).
|
||||
* If there is not enough space, return NULL.
|
||||
*/
|
||||
void* main_pool_alloc(u32 size, u32 side) {
|
||||
void* main_pool_alloc_from_pool(u32 size, u32 side) {
|
||||
struct MainPoolBlock* newListHead;
|
||||
void* addr = NULL;
|
||||
|
||||
size = ALIGN16(size) + sizeof(struct MainPoolBlock);
|
||||
if (size != 0 && sMemPool.available >= size) {
|
||||
|
||||
// do we have enough space?
|
||||
if (size > 0 && size <= sMemPool.available) {
|
||||
if (side == MEMORY_POOL_LEFT) {
|
||||
// reduce available size.
|
||||
sMemPool.available -= size;
|
||||
newListHead = (void*)((uintptr_t)sMemPool.listHeadL + size);
|
||||
sMemPool.listHeadL->next = newListHead;
|
||||
newListHead->prev = sMemPool.listHeadL;
|
||||
newListHead->next = NULL;
|
||||
newListHead->func = 0;
|
||||
newListHead->arg = 0;
|
||||
newListHead->func = NULL;
|
||||
newListHead->arg = '\0';
|
||||
addr = ((u8*)sMemPool.listHeadL + sizeof(struct MainPoolBlock));
|
||||
sMemPool.listHeadL = newListHead;
|
||||
} else if (side == MEMORY_POOL_RIGHT) {
|
||||
// reduce available size.
|
||||
sMemPool.available -= size;
|
||||
newListHead = (void*)((uintptr_t)sMemPool.listHeadR - size);
|
||||
sMemPool.listHeadR->prev = newListHead;
|
||||
newListHead->next = sMemPool.listHeadR;
|
||||
newListHead->prev = NULL;
|
||||
newListHead->func = 0;
|
||||
newListHead->arg = 0;
|
||||
newListHead->func = NULL;
|
||||
newListHead->arg = '\0';
|
||||
sMemPool.listHeadR = newListHead;
|
||||
addr = ((u8*)newListHead + sizeof(struct MainPoolBlock));
|
||||
}
|
||||
|
|
@ -84,7 +88,7 @@ u32 main_pool_free(void* addr, u32 runBlockFunc) {
|
|||
// TODO: Fakematch
|
||||
void (*func)(struct MainPoolBlock*, u32) = block->func;
|
||||
if (func != 0) {
|
||||
block->func(block + 1, block->arg);
|
||||
block->func((u8*)block + sizeof(struct MainPoolBlock), block->arg);
|
||||
// TODO: fake here too
|
||||
if ((!(&sMemPool)) && (!(&sMemPool))) {}
|
||||
}
|
||||
|
|
@ -99,7 +103,7 @@ u32 main_pool_free(void* addr, u32 runBlockFunc) {
|
|||
if (runBlockFunc) {
|
||||
void (*func)(struct MainPoolBlock*, u32) = block->func;
|
||||
if (func != NULL) {
|
||||
func(block + 1, block->arg);
|
||||
func((u8*)block + sizeof(struct MainPoolBlock), block->arg);
|
||||
block = sMemPool.listHeadR;
|
||||
}
|
||||
}
|
||||
|
|
@ -118,27 +122,27 @@ u32 main_pool_free(void* addr, u32 runBlockFunc) {
|
|||
* Manually allocate and initialize a block given a size and side and its
|
||||
* function+arguments.
|
||||
*/
|
||||
void* main_pool_alloc_node(u32 size, s32 side, s32 arg, void* func) {
|
||||
struct MainPoolBlock* node;
|
||||
void* main_pool_alloc_with_func(u32 size, s32 side, s32 arg, void* func) {
|
||||
struct MainPoolBlock* addr;
|
||||
|
||||
osRecvMesg(&sMemPool.queue, NULL, OS_MESG_BLOCK);
|
||||
node = main_pool_alloc(size, side);
|
||||
if (node != NULL) {
|
||||
main_pool_set_func(node, arg, func);
|
||||
addr = main_pool_alloc_from_pool(size, side);
|
||||
if (addr != NULL) {
|
||||
main_pool_set_func(addr, arg, func);
|
||||
}
|
||||
osSendMesg(&sMemPool.queue, NULL, OS_MESG_NOBLOCK);
|
||||
|
||||
return node;
|
||||
return addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as above but no function/argument is set.
|
||||
*/
|
||||
void* main_pool_alloc_node_no_func(u32 size, s32 side) {
|
||||
void* main_pool_alloc(u32 size, s32 side) {
|
||||
struct MainPoolBlock* node;
|
||||
|
||||
osRecvMesg(&sMemPool.queue, NULL, OS_MESG_BLOCK);
|
||||
node = main_pool_alloc(size, side);
|
||||
node = main_pool_alloc_from_pool(size, side);
|
||||
osSendMesg(&sMemPool.queue, NULL, OS_MESG_NOBLOCK);
|
||||
|
||||
return node;
|
||||
|
|
@ -148,10 +152,10 @@ void* main_pool_alloc_node_no_func(u32 size, s32 side) {
|
|||
* Tries to free a block of memory that was allocated from the pool. Return
|
||||
* the new available amount of the pool.
|
||||
*/
|
||||
u32 main_pool_try_free(struct MainPoolBlock* addr) {
|
||||
u32 main_pool_try_free(void* addr) {
|
||||
if (addr != NULL) {
|
||||
osRecvMesg(&sMemPool.queue, NULL, OS_MESG_BLOCK);
|
||||
main_pool_free(addr, 1);
|
||||
main_pool_free(addr, TRUE);
|
||||
osSendMesg(&sMemPool.queue, NULL, OS_MESG_NOBLOCK);
|
||||
}
|
||||
|
||||
|
|
@ -170,14 +174,17 @@ void* main_pool_realloc(void* addr, size_t size) {
|
|||
|
||||
osRecvMesg(&sMemPool.queue, NULL, OS_MESG_BLOCK);
|
||||
|
||||
// most recently allocated block?
|
||||
if (prior->next == sMemPool.listHeadL) {
|
||||
size_t diff = ((uintptr_t)prior->next - (uintptr_t)addr);
|
||||
size = ALIGN16(size);
|
||||
|
||||
// is there enough room to expand/realloc the area?
|
||||
if (diff >= size || sMemPool.available >= (size - diff)) {
|
||||
s32 arg = prior->arg;
|
||||
void* func = prior->func;
|
||||
main_pool_free(addr, 0);
|
||||
newaddr = main_pool_alloc(size, MEMORY_POOL_LEFT);
|
||||
main_pool_free(addr, FALSE); // do not run the func as we are merely reallocating it.
|
||||
newaddr = main_pool_alloc_from_pool(size, MEMORY_POOL_LEFT);
|
||||
main_pool_set_func(newaddr, arg, func);
|
||||
}
|
||||
}
|
||||
|
|
@ -189,8 +196,12 @@ void* main_pool_realloc(void* addr, size_t size) {
|
|||
* Return the amount of available memory to use in the pool.
|
||||
*/
|
||||
u32 main_pool_get_available(void) {
|
||||
// account for the block struct. Any newly allocated pools have this struct as its "true"
|
||||
// header, so subtract the size to get the real amount of available space.
|
||||
s32 available = sMemPool.available - sizeof(struct MainPoolBlock);
|
||||
|
||||
// if it was less than 0, then we do not have enough to allocate a single pool. Floor the
|
||||
// practical amount of available space to 0.
|
||||
if (available < 0) {
|
||||
available = 0;
|
||||
}
|
||||
|
|
@ -215,11 +226,19 @@ u32 main_pool_push_state(u32 arg) {
|
|||
listHeadL = sMemPool.listHeadL;
|
||||
listHeadR = sMemPool.listHeadR;
|
||||
|
||||
state = main_pool_alloc(sizeof(struct MainPoolState), MEMORY_POOL_LEFT);
|
||||
/**
|
||||
* We are essentially allocating a block that looks like this:
|
||||
*
|
||||
* struct AllocatedBlock {
|
||||
* struct MainPoolBlock block;
|
||||
* struct MainPoolState state; <---- the pointer is pointing here.
|
||||
* };
|
||||
*/
|
||||
state = main_pool_alloc_from_pool(sizeof(struct MainPoolState), MEMORY_POOL_LEFT);
|
||||
if (state != NULL) {
|
||||
/**
|
||||
* Why is this line here? What this line is doing is backing the pointer up to the
|
||||
* previous block before this one. in the block alloc function, addr is determined
|
||||
* previous block before the state. In the block alloc function, addr is determined
|
||||
* by the head plus the size of the block struct, meaning it is returning the
|
||||
* pointer to the head.
|
||||
*/
|
||||
|
|
@ -250,7 +269,6 @@ u32 main_pool_pop_state(u32 arg) {
|
|||
void* listHeadR;
|
||||
struct MainPoolState* state;
|
||||
|
||||
argptr = (u32)arg;
|
||||
osRecvMesg(&sMemPool.queue, NULL, OS_MESG_BLOCK);
|
||||
|
||||
do {
|
||||
|
|
@ -260,38 +278,49 @@ u32 main_pool_pop_state(u32 arg) {
|
|||
sMemPool.available = node->freeSpace;
|
||||
sMemPool.mainState = node->prev;
|
||||
|
||||
// was the argument passed in 0?
|
||||
if (argptr == 0) {
|
||||
// was the argument passed in blank?
|
||||
if (arg == '\0') {
|
||||
break;
|
||||
}
|
||||
|
||||
// odd reuse of the variable, but what this is doing is backing the ptr up to the
|
||||
// pool block. Thus, to check the arg variable on the pool block located before the state,
|
||||
// we will need to cast the next if check.
|
||||
/**
|
||||
* Odd reuse of the variable, but what this is doing is backing the ptr up to the
|
||||
* pool block. Thus, to check the arg variable on the pool block located before the state,
|
||||
* we will need to cast the next if check.
|
||||
*/
|
||||
node = (void*)((u8*)node - sizeof(struct MainPoolState));
|
||||
|
||||
if ((uintptr_t)argptr == (uintptr_t)((struct MainPoolBlock*)node)->arg) {
|
||||
// we found the block with the matching string! break.
|
||||
if (arg == (uintptr_t)((struct MainPoolBlock*)node)->arg) {
|
||||
// we found the block with the matching string! That means we are now at the
|
||||
// beginning of the pool area and can begin to run the function loops. Break.
|
||||
break;
|
||||
}
|
||||
} while (sMemPool.mainState != NULL);
|
||||
|
||||
/**
|
||||
* For every block pool in the main pool being popped, try to run the function set by its
|
||||
* main pool state. Repeat until we have cleared the right pool side.
|
||||
*/
|
||||
argptr = sMemPool.listHeadR;
|
||||
while ((uintptr_t)listHeadR > (uintptr_t)argptr) {
|
||||
if (argptr->func != NULL) {
|
||||
argptr->func(argptr + 1, argptr->arg);
|
||||
argptr->func((u8*)argptr + sizeof(struct MainPoolBlock), argptr->arg);
|
||||
}
|
||||
argptr = argptr->next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as above, but for the left side.
|
||||
*/
|
||||
argptr = sMemPool.listHeadL->prev;
|
||||
while ((uintptr_t)listHeadL <= (uintptr_t)argptr) {
|
||||
if (argptr->func != NULL) {
|
||||
argptr->func(argptr + 1, argptr->arg);
|
||||
argptr->func((u8*)argptr + sizeof(struct MainPoolBlock), argptr->arg);
|
||||
}
|
||||
argptr = argptr->prev;
|
||||
}
|
||||
|
||||
// set the new left and right sides and queue and return.
|
||||
sMemPool.listHeadL = listHeadL;
|
||||
sMemPool.listHeadR = listHeadR;
|
||||
osSendMesg(&sMemPool.queue, NULL, OS_MESG_NOBLOCK);
|
||||
|
|
|
|||
|
|
@ -570,12 +570,12 @@ Util_DrawRect = 0x8000302C;
|
|||
Util_Memclear = 0x8000330C;
|
||||
UnkHeapThing = 0x80104BC0;
|
||||
gMemPool = 0x800A6070;
|
||||
main_pool_alloc = 0x80002380;
|
||||
main_pool_alloc_from_pool = 0x80002380;
|
||||
main_pool_get_available = 0x80002764;
|
||||
main_pool_free = 0x80002430;
|
||||
main_pool_set_func = 0x80002A14;
|
||||
main_pool_alloc_node = 0x8000254C;
|
||||
main_pool_alloc_node_no_func = 0x800025C4;
|
||||
main_pool_alloc_with_func = 0x8000254C;
|
||||
main_pool_alloc = 0x800025C4;
|
||||
main_pool_try_free = 0x80002620;
|
||||
main_pool_realloc = 0x80002680;
|
||||
main_pool_push_state = 0x80002784;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user