summaryrefslogtreecommitdiff
path: root/arm9/lib/src
diff options
context:
space:
mode:
authorPikalaxALT <pikalaxalt@gmail.com>2020-05-01 07:54:42 -0400
committerPikalaxALT <pikalaxalt@gmail.com>2020-05-01 07:54:42 -0400
commit9137144cc872024e7bf193b46b755330d66e343f (patch)
tree191c1c257dfceac54525667d4c620a7eb81e32fd /arm9/lib/src
parent6c3731902319116e8e73b14e2b75d5fd8c9642ff (diff)
parent90d38f053ff21a5d6cd967de29dc440cbba9aa29 (diff)
Merge branch 'master' of https://github.com/martmists/pokediamond into pikalax_work
Diffstat (limited to 'arm9/lib/src')
-rw-r--r--arm9/lib/src/OS_alloc.c169
-rw-r--r--arm9/lib/src/OS_arena.c22
2 files changed, 180 insertions, 11 deletions
diff --git a/arm9/lib/src/OS_alloc.c b/arm9/lib/src/OS_alloc.c
new file mode 100644
index 00000000..242c5571
--- /dev/null
+++ b/arm9/lib/src/OS_alloc.c
@@ -0,0 +1,169 @@
+//
+// Created by mart on 4/23/20.
+//
+#include "function_target.h"
+#include "os_alloc.h"
+#include "consts.h"
+#include "os_system.h"
+
+void* OSiHeapInfo[OS_ARENA_MAX];
+
+ARM_FUNC Cell* DLAddFront(Cell* list, Cell* cell)
+{
+ cell->next = list;
+ cell->prev = NULL;
+
+ if (list != NULL)
+ list->prev = cell;
+ return cell;
+}
+
+ARM_FUNC Cell* DLExtract(Cell* list, Cell* cell)
+{
+ if (cell->next) {
+ cell->next->prev = cell->prev;
+ }
+ if (cell->prev == NULL) {
+ list = cell->next;
+ } else {
+ cell->prev->next = cell->next;
+ }
+ return list;
+}
+
+ARM_FUNC Cell *DLInsert(Cell *original, Cell *inserted)
+{
+ Cell *prevCell = NULL;
+ Cell *nextCell = original;
+
+
+ while (nextCell != NULL)
+ {
+ if (inserted <= nextCell)
+ break;
+ prevCell = nextCell;
+ nextCell = nextCell->next;
+ }
+
+ inserted->next = nextCell;
+ inserted->prev = prevCell;
+
+ if (nextCell != NULL)
+ {
+ nextCell->prev = inserted;
+ Cell * temp = (Cell *)((char *)inserted + inserted->size);
+ if (temp == nextCell)
+ {
+ inserted->size += nextCell->size;
+ nextCell = nextCell->next;
+ inserted->next = nextCell;
+ if (nextCell != NULL)
+ nextCell->prev = inserted;
+ }
+ }
+
+ if (prevCell != NULL)
+ {
+ prevCell->next = inserted;
+ Cell * temp = (Cell *)((char *)prevCell + prevCell->size);
+
+ if (temp != inserted)
+ return original;
+
+ prevCell->size += inserted->size;
+ prevCell->next = nextCell;
+ if (nextCell != NULL)
+ nextCell->prev = prevCell;
+
+ return original;
+ }
+
+ return inserted;
+}
+
+#define HEADERSIZE OSi_ROUND(sizeof(Cell), 32)
+#define MINOBJSIZE (HEADERSIZE+32)
+
+ARM_FUNC void* OS_AllocFromHeap(OSArenaId id, OSHeapHandle heap, u32 size) {
+ OSHeapInfo* heapInfo;
+ HeapDesc* hd;
+ Cell* cell;
+ Cell* newCell;
+ long leftoverSize;
+
+ OSIntrMode enabled = OS_DisableInterrupts();
+ heapInfo = OSiHeapInfo[id];
+ if (!heapInfo) {
+ OS_RestoreInterrupts(enabled);
+ return NULL;
+ }
+
+ if (heap < 0) {
+ heap = heapInfo->currentHeap;
+ }
+
+ hd = &heapInfo->heapArray[heap];
+
+ size += HEADERSIZE;
+ size = OSi_ROUND(size, 32);
+
+ for (cell = hd->free; cell != NULL; cell = cell->next) {
+ if ((long)size <= cell->size) {
+ break;
+ }
+ }
+
+ if (cell == NULL) {
+ OS_RestoreInterrupts(enabled);
+ return NULL;
+ }
+
+ leftoverSize = cell->size - (long)size;
+ if (leftoverSize < MINOBJSIZE) {
+ hd->free = DLExtract(hd->free, cell);
+ } else {
+ cell->size = (long)size;
+
+ newCell = (Cell *) ((char *)cell + size);
+ newCell->size = leftoverSize;
+
+ newCell->prev = cell->prev;
+ newCell->next = cell->next;
+
+ if (newCell->next != NULL) {
+ newCell->next->prev = newCell;
+ }
+
+ if (newCell->prev != NULL) {
+ newCell->prev->next = newCell;
+ } else {
+ hd->free = newCell;
+ }
+ }
+
+ hd->allocated = DLAddFront(hd->allocated, cell);
+
+ OS_RestoreInterrupts(enabled);
+ return (void *)((char *)cell + HEADERSIZE);
+}
+
+ARM_FUNC void OS_FreeToHeap(OSArenaId id, OSHeapHandle heap, void* ptr) {
+ OSHeapInfo *heapInfo;
+ HeapDesc *hd;
+ Cell *cell;
+
+ OSIntrMode enabled = OS_DisableInterrupts();
+ heapInfo = OSiHeapInfo[id];
+
+ if (heap < 0) {
+ heap = heapInfo->currentHeap;
+ }
+
+ cell = (Cell *) ((char *)ptr - HEADERSIZE);
+ hd = &heapInfo->heapArray[heap];
+
+ hd->allocated = DLExtract(hd->allocated, cell);
+ hd->free = DLInsert(hd->free, cell);
+
+ OS_RestoreInterrupts(enabled);
+}
diff --git a/arm9/lib/src/OS_arena.c b/arm9/lib/src/OS_arena.c
index b4bcbc1c..58b338f1 100644
--- a/arm9/lib/src/OS_arena.c
+++ b/arm9/lib/src/OS_arena.c
@@ -1,7 +1,7 @@
//
// Created by red031000 on 2020-04-27.
//
-
+#include "function_target.h"
#include "consts.h"
#include "os_arena.h"
#include "os_protectionRegion.h"
@@ -16,7 +16,7 @@ extern void SDK_SECTION_ARENA_DTCM_START(); // TODO: technically this should be
extern void SDK_IRQ_STACKSIZE(); // TODO: technically this should be defined in the lcf
extern void SDK_SYS_STACKSIZE(); // TODO: technically this should be defined in the lcf
-void OS_InitArena() {
+ARM_FUNC void OS_InitArena() {
if (OSi_Initialized) {
return;
}
@@ -41,7 +41,7 @@ void OS_InitArena() {
OS_SetArenaLo(OS_ARENA_WRAM_MAIN, OS_GetInitArenaLo(OS_ARENA_WRAM_MAIN));
}
-void OS_InitArenaEx() {
+ARM_FUNC void OS_InitArenaEx() {
OS_SetArenaHi(2, OS_GetInitArenaHi(OS_ARENA_MAINEX));
OS_SetArenaLo(2, OS_GetInitArenaLo(OS_ARENA_MAINEX));
@@ -51,15 +51,15 @@ void OS_InitArenaEx() {
}
}
-void* OS_GetArenaHi(OSArenaId id) {
+ARM_FUNC void* OS_GetArenaHi(OSArenaId id) {
return OSi_GetArenaInfo().hi[id];
}
-void* OS_GetArenaLo(OSArenaId id) {
+ARM_FUNC void* OS_GetArenaLo(OSArenaId id) {
return OSi_GetArenaInfo().lo[id];
}
-void* OS_GetInitArenaHi(OSArenaId id) {
+ARM_FUNC void* OS_GetInitArenaHi(OSArenaId id) {
switch (id) {
case OS_ARENA_MAIN:
return (void *)OSi_MAIN_ARENA_HI_DEFAULT;
@@ -97,7 +97,7 @@ void* OS_GetInitArenaHi(OSArenaId id) {
}
}
-void* OS_GetInitArenaLo(OSArenaId id) {
+ARM_FUNC void* OS_GetInitArenaLo(OSArenaId id) {
switch (id) {
case OS_ARENA_MAIN:
return (void *)SDK_MAIN_ARENA_LO;
@@ -120,15 +120,15 @@ void* OS_GetInitArenaLo(OSArenaId id) {
}
}
-void OS_SetArenaHi(OSArenaId id, void* newHi) {
+ARM_FUNC void OS_SetArenaHi(OSArenaId id, void* newHi) {
OSi_GetArenaInfo().hi[id] = newHi;
}
-void OS_SetArenaLo(OSArenaId id, void* newLo) {
+ARM_FUNC void OS_SetArenaLo(OSArenaId id, void* newLo) {
OSi_GetArenaInfo().lo[id] = newLo;
}
-void* OS_AllocFromArenaLo(OSArenaId id, u32 size, u32 align) {
+ARM_FUNC void* OS_AllocFromArenaLo(OSArenaId id, u32 size, u32 align) {
void* ptr;
u8* arenaLo;
ptr = OS_GetArenaLo(id);
@@ -146,7 +146,7 @@ void* OS_AllocFromArenaLo(OSArenaId id, u32 size, u32 align) {
return ptr;
}
-void* OS_AllocFromArenaHi(OSArenaId id, u32 size, u32 align) {
+ARM_FUNC void* OS_AllocFromArenaHi(OSArenaId id, u32 size, u32 align) {
void* ptr;
u8* arenaHi;