tp/libs/dolphin/os/OSAlloc.c

141 lines
3.7 KiB
C

#include "dolphin/os/OSAlloc.h"
/* 8033B078-8033B124 3359B8 00AC+00 1/1 0/0 0/0 .text DLInsert */
static OSHeapCell* DLInsert(OSHeapCell* list, OSHeapCell* child) {
OSHeapCell* prev = NULL;
OSHeapCell* next = list;
for (; next != NULL; prev = next, next = next->next) {
if ((char*)child <= (char*)next) {
break;
}
}
child->next = next;
child->prev = prev;
if (next != NULL) {
next->prev = child;
if ((char*)child + child->size == (char*)next) {
child->size += next->size;
next = next->next;
child->next = next;
if (next != NULL) {
next->prev = child;
}
}
}
if (prev != NULL) {
prev->next = child;
if ((char*)prev + prev->size == (char*)child) {
prev->size += child->size;
prev->next = next;
if (next != NULL) {
next->prev = prev;
}
}
return list;
} else {
return child;
}
}
inline OSHeapCell* DLExtract(OSHeapCell* list, OSHeapCell* child) {
if (child->next != NULL) {
child->next->prev = child->prev;
}
if (child->prev == NULL) {
return child->next;
}
child->prev->next = child->next;
return list;
}
/* ############################################################################################## */
/* 80451640-80451644 000B40 0004+00 3/3 0/0 0/0 .sbss HeapArray */
static OSHeapDescriptor* HeapArray;
/* 8033B124-8033B1A0 335A64 007C+00 0/0 1/1 0/0 .text OSFreeToHeap */
void OSFreeToHeap(OSHeapHandle handle, void* ptr) {
OSHeapDescriptor* hd = &HeapArray[handle];
OSHeapCell* cell = (OSHeapCell*)((char*)ptr - sizeof(OSHeapCell));
hd->usedList = DLExtract(hd->usedList, cell);
hd->freeList = DLInsert(hd->freeList, cell);
}
/* ############################################################################################## */
/* 80450990-80450998 000410 0004+04 2/2 1/1 0/0 .sdata __OSCurrHeap */
volatile s32 __OSCurrHeap = -1;
/* 8033B1A0-8033B1B0 335AE0 0010+00 0/0 1/1 0/0 .text OSSetCurrentHeap */
s32 OSSetCurrentHeap(OSHeapHandle handle) {
s32 old = __OSCurrHeap;
__OSCurrHeap = handle;
return old;
}
/* ############################################################################################## */
/* 80451644-80451648 000B44 0004+00 2/2 0/0 0/0 .sbss NumHeaps */
static s32 NumHeaps;
/* 80451648-8045164C 000B48 0004+00 1/1 0/0 0/0 .sbss ArenaStart */
static void* ArenaStart;
/* 8045164C-80451650 000B4C 0004+00 1/1 0/0 0/0 .sbss ArenaEnd */
static void* ArenaEnd;
/* 8033B1B0-8033B220 335AF0 0070+00 0/0 2/2 0/0 .text OSInitAlloc */
void* OSInitAlloc(void* lo, void* hi, s32 maxHeaps) {
u32 totalSize = maxHeaps * sizeof(OSHeapDescriptor);
int i;
HeapArray = lo;
NumHeaps = maxHeaps;
for (i = 0; i < NumHeaps; i++) {
OSHeapDescriptor* hd = &HeapArray[i];
hd->size = -1;
hd->freeList = hd->usedList = NULL;
}
__OSCurrHeap = -1;
lo = (u8*)HeapArray + totalSize;
lo = OSRoundUpPtr(lo, 0x20);
ArenaStart = lo;
ArenaEnd = OSRoundDownPtr(hi, 0x20);
return ArenaStart;
}
/* 8033B220-8033B28C 335B60 006C+00 0/0 1/1 0/0 .text OSCreateHeap */
OSHeapHandle OSCreateHeap(void* start, void* end) {
int i;
OSHeapCell* cell = OSRoundUpPtr(start, 0x20);
end = OSRoundDownPtr(end, 0x20);
for (i = 0; i < NumHeaps; i++) {
OSHeapDescriptor* hd = &HeapArray[i];
if (hd->size < 0) {
hd->size = (u8*)end - (u8*)cell;
cell->prev = NULL;
cell->next = NULL;
cell->size = hd->size;
hd->freeList = cell;
hd->usedList = NULL;
return i;
}
}
return -1;
}