From 81015d600b49ab26fd4bb40f57ef82978856ee14 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Mon, 10 Nov 2025 18:36:27 +0100 Subject: [PATCH] ulib Non-partitioned umalloc implementation --- ulib/linearlist.h | 3 +- ulib/umalloc/umalloc.c | 153 ++++------------------------------------- ulib/umalloc/umalloc.h | 4 +- 3 files changed, 15 insertions(+), 145 deletions(-) diff --git a/ulib/linearlist.h b/ulib/linearlist.h index 15be0e3..712ce17 100644 --- a/ulib/linearlist.h +++ b/ulib/linearlist.h @@ -11,8 +11,9 @@ (lst)->data = umalloc(sizeof(*(lst)->data) * (lst)->capacity); \ } else { \ if ((lst)->count == (lst)->capacity) { \ + size_t __oldcap = (lst)->capacity; \ (lst)->capacity *= 2; \ - (lst)->data = urealloc((lst)->data, sizeof(*(lst)->data) * (lst)->capacity); \ + (lst)->data = urealloc((lst)->data, sizeof(*(lst)->data) * __oldcap, sizeof(*(lst)->data) * (lst)->capacity); \ } \ } \ (lst)->data[(lst)->count++] = (d); \ diff --git a/ulib/umalloc/umalloc.c b/ulib/umalloc/umalloc.c index 0c6390c..b4e3e8b 100644 --- a/ulib/umalloc/umalloc.c +++ b/ulib/umalloc/umalloc.c @@ -9,147 +9,7 @@ #include #include -#define ARENA_SIZE (1<<20) -#define BLOCK_MAGIC 0xDEADBEEF - -typedef struct UmArena { - struct UmArena *next; - uintptr_t mem; - uintptr_t base; - size_t cursor; - int64_t balance; -} __attribute__((aligned(16))) UmArena; - -typedef struct { - uint32_t magic; - size_t size; - uint8_t data[]; -} __attribute__((aligned(16))) UmBlock; - -static UmArena *ARENAS = NULL; - -UmArena *um_newarena(void) { - size_t arenasize = ARENA_SIZE; - - uint8_t *mem = NULL; - int32_t err = mman_map(NULL, arenasize, MMAN_MAP_PF_RW, 0, &mem); - if (mem == NULL || err != E_OK) { - return NULL; - } - - UmArena *arena = (UmArena *)mem; - arena->base = (uintptr_t)mem; - arena->mem = ((uintptr_t)mem + sizeof(UmArena) + 15) & ~0xF; - arena->cursor = 0; - arena->balance = 0; - LL_APPEND(ARENAS, arena); - - return arena; -} - void *umalloc(size_t size) { - UmArena *usable = NULL; - - size = (size + 15) & ~(size_t)0xF; - - UmArena *arena, *arenatmp; - LL_FOREACH_SAFE(ARENAS, arena, arenatmp) { - if (arena->cursor + sizeof(UmBlock) + size <= ARENA_SIZE - ((uintptr_t)arena->mem - arena->base)) { - usable = arena; - break; - } - } - - if (usable == NULL) { - usable = um_newarena(); - } - - if (usable == NULL) { - return NULL; - } - - uintptr_t addr = usable->mem + usable->cursor; - UmBlock *block = (UmBlock *)addr; - block->size = size; - block->magic = BLOCK_MAGIC; - - usable->cursor += sizeof(UmBlock) + size; - usable->balance += size; - - string_memset(block->data, 0, size); - return block->data; -} - -void ufree(void *ptr_) { - if (ptr_ == NULL) { - return; - } - - uintptr_t ptr = (uintptr_t)ptr_; - - UmArena *freeable = NULL; - size_t size = 0; - - UmArena *arena, *arenatmp; - LL_FOREACH_SAFE(ARENAS, arena, arenatmp) { - if (ptr >= arena->mem && ptr < arena->mem + arena->cursor) { - UmBlock *block = (UmBlock *)(ptr - sizeof(UmBlock)); - - if (((uintptr_t)block->data != ptr) - || (block->magic != BLOCK_MAGIC) - || (block->size == 0) - || (block->size > ARENA_SIZE)) { - return; - } - - string_memset(block->data, 0xDD, block->size); - block->magic = 0; - - arena->balance -= block->size; - ASSERT(arena->balance >= 0, "umalloc: imbalance after free\n"); - - if (arena->balance == 0) { - LL_REMOVE(ARENAS, arena); - mman_unmap((void *)arena->base); - } - - return; - } - } -} - -void *urealloc(void *ptr, size_t newsize) { - void *new; - - UmBlock *block = (UmBlock *)(ptr - sizeof(UmBlock)); - if (block->magic != BLOCK_MAGIC || block->data != ptr) { - goto err; - } - - if (!ptr) { - new = umalloc(newsize); - if (!new) { - goto err; - } - } else { - if (block->size < newsize) { - new = umalloc(newsize); - if (!new) { - goto err; - } - string_memcpy(new, ptr, block->size); - ufree(ptr); - } else { - new = ptr; - } - } - return new; - -err: - return NULL; -} - -void *umallocbig(size_t size) { size_t allocsz = ALIGN_UP(size, 4096); uint8_t *out; int32_t ret = mman_map(NULL, allocsz, MMAN_MAP_PF_RW, 0, &out); @@ -159,7 +19,18 @@ void *umallocbig(size_t size) { return out; } -void ufreebig(void *addr) { +void ufree(void *addr) { if (addr != NULL) mman_unmap(addr); } + +void *urealloc(void *addr, size_t oldsize, size_t newsize) { + void *tmp = umalloc(newsize); + if (tmp == NULL) { + return NULL; + } + string_memset(tmp, 0, newsize); + string_memcpy(tmp, addr, oldsize); + ufree(addr); + return tmp; +} diff --git a/ulib/umalloc/umalloc.h b/ulib/umalloc/umalloc.h index c83bb28..827e0c3 100644 --- a/ulib/umalloc/umalloc.h +++ b/ulib/umalloc/umalloc.h @@ -6,8 +6,6 @@ void *umalloc(size_t size); void ufree(void *ptr_); -void *urealloc(void *ptr, size_t newsize); -void *umallocbig(size_t size); -void ufreebig(void *addr); +void *urealloc(void *ptr, size_t oldsize, size_t newsize); #endif // ULIB_UMALLOC_UMALLOC_H_