From 190b78549e0fa1a801786e73d914185e1fbca2a6 Mon Sep 17 00:00:00 2001 From: Derek Hensley Date: Mon, 11 Sep 2023 17:38:31 -0700 Subject: Non libultra Boot Cleanup (#1370) * reorganize * math64 * rcp_utils * osSyncPrintfUnused * comment spacing --- src/boot/O2/stackcheck.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 src/boot/O2/stackcheck.c (limited to 'src/boot/O2/stackcheck.c') diff --git a/src/boot/O2/stackcheck.c b/src/boot/O2/stackcheck.c new file mode 100644 index 000000000..edd1e3a30 --- /dev/null +++ b/src/boot/O2/stackcheck.c @@ -0,0 +1,122 @@ +#include "stackcheck.h" +#include "libc/stdbool.h" +#include "libc/stdint.h" + +StackEntry* sStackInfoListStart = NULL; +StackEntry* sStackInfoListEnd = NULL; + +void StackCheck_Init(StackEntry* entry, void* stackBottom, void* stackTop, u32 initValue, s32 minSpace, + const char* name) { + if (entry == NULL) { + sStackInfoListStart = NULL; + } else { + StackEntry* iter; + + entry->head = stackBottom; + entry->tail = stackTop; + entry->initValue = initValue; + entry->minSpace = minSpace; + entry->name = name; + iter = sStackInfoListStart; + while (iter) { + if (iter == entry) { + return; + } + iter = iter->next; + } + + entry->prev = sStackInfoListEnd; + entry->next = NULL; + + if (sStackInfoListEnd) { + sStackInfoListEnd->next = entry; + } + + sStackInfoListEnd = entry; + if (sStackInfoListStart == NULL) { + sStackInfoListStart = entry; + } + + if (entry->minSpace != -1) { + u32* addr = entry->head; + + while (addr < (u32*)entry->tail) { + *addr++ = entry->initValue; + } + } + } +} + +void StackCheck_Cleanup(StackEntry* entry) { + u32 inconsistency = false; + + if (entry->prev == NULL) { + if (entry == sStackInfoListStart) { + sStackInfoListStart = entry->next; + } else { + inconsistency = true; + } + } else { + entry->prev->next = entry->next; + } + + if (!entry->next) { + if (entry == sStackInfoListEnd) { + sStackInfoListEnd = entry->prev; + } else { + inconsistency = true; + } + } + + if (inconsistency) {} +} + +StackStatus StackCheck_GetState(StackEntry* entry) { + u32* last; + size_t used; + size_t free; + StackStatus status; + + for (last = entry->head; last < (u32*)entry->tail; last++) { + if (entry->initValue != *last) { + break; + } + } + + used = (uintptr_t)entry->tail - (uintptr_t)last; + free = (uintptr_t)last - (uintptr_t)entry->head; + + if (free == 0) { + status = STACK_STATUS_OVERFLOW; + } else if ((free < (size_t)entry->minSpace) && (entry->minSpace != -1)) { + status = STACK_STATUS_WARNING; + } else { + status = STACK_STATUS_OK; + } + + return status; +} + +u32 StackCheck_CheckAll(void) { + u32 ret = 0; + StackEntry* iter = sStackInfoListStart; + + while (iter != NULL) { + StackStatus state = StackCheck_GetState(iter); + + if (state != STACK_STATUS_OK) { + ret = 1; + } + iter = iter->next; + } + + return ret; +} + +u32 StackCheck_Check(StackEntry* entry) { + if (entry == NULL) { + return StackCheck_CheckAll(); + } else { + return StackCheck_GetState(entry); + } +} -- cgit v1.2.3