commit 27b147c5e407c97b642fe5679b512972871ed81d parent 71bedc51ed68cfa9be1044ca7663c2980edc011b Author: finwo <finwo@pm.me> Date: Wed, 11 Sep 2019 21:25:54 +0200 free should now work with malloc Diffstat:
| M | lib/c/malloc.c | | | 53 | ++++++++++++++++++++++++++++++++++++++++++++++++----- |
1 file changed, 48 insertions(+), 5 deletions(-)
diff --git a/lib/c/malloc.c b/lib/c/malloc.c @@ -1,17 +1,60 @@ +#include "./null.c" extern unsigned char __heap_base; unsigned int bump_pointer = &__heap_base; +unsigned int heap_start = &__heap_base; +unsigned int heap_end = &__heap_base; +unsigned int isize = sizeof(unsigned int); +unsigned int hsize = (2 * sizeof(unsigned int)); + // TODO: realloc // TODO: free void* malloc(int n) { - unsigned int r = bump_pointer; - bump_pointer += n; - return (void *)r; + unsigned int r = heap_start; + + unsigned int *size = NULL; + unsigned int *used = NULL; + + // Loop through known blocks + while(r < heap_end) { + size = (void*)r; + used = (void*)(r+isize); + + // In-use = skip + if (*used) { + r += *size; + continue; + } + + // Too small = skip + if ((*size) < (n + hsize)) { + r += *size; + continue; + } + + // Take this block + *used = n; + return (void*)(r + hsize); + } + + // Something went wrong + if (r < heap_end) { + return NULL; + } + + // Build a new block + size = (void*)r; + used = (void*)(r+isize); + *size = n + hsize; + *used = n; + heap_end = r + n + hsize; + return (void*)(r + hsize); } -void free(void* p) { - // lol +void free(void *p) { + unsigned int *used = p - isize; + *used = 0; }