diff options
Diffstat (limited to 'memory.c')
-rw-r--r-- | memory.c | 275 |
1 files changed, 0 insertions, 275 deletions
diff --git a/memory.c b/memory.c deleted file mode 100644 index 0d9fe13..0000000 --- a/memory.c +++ /dev/null @@ -1,275 +0,0 @@ -/* Copyright (C) 2025 Aryadev Chavali - - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License Version 2 for - * details. - - * You may distribute and modify this code under the terms of the GNU General - * Public License Version 2, which you should have received a copy of along with - * this program. If not, please go to <https://www.gnu.org/licenses/>. - - * Created: 2025-04-05 - * Description: Implementations for memory models. - */ - -#include "./memory.h" - -#include <malloc.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -page_t *page_create(u64 size) -{ - size = MAX(size, PAGE_DEFAULT_SIZE); - page_t *page = calloc(1, sizeof(*page) + size); - page->next = NULL; - page->size = 0; - page->capacity = size; - return page; -} - -void page_resize(page_t **page, u64 size) -{ - if (!page) - return; - else if (!(*page)) - *page = page_create(size); - else if (page[0]->capacity < size) - { - page[0]->capacity = MAX(size, page[0]->capacity * 1.5); - page[0] = realloc(page[0], sizeof(*page[0]) + page[0]->capacity); - } -} - -i64 page_append(page_t *page, void *data, u64 size) -{ - if (!page || page->size + size >= page->capacity) - return -1; - if (data) - memcpy(page->data + page->size, data, size); - u64 ptr = page->size; - page->size += size; - return ptr; -} - -u64 page_rappend(page_t **page, void *data, u64 size) -{ - page_resize(page, page[0]->size + size); - if (data) - memcpy(page[0]->data + page[0]->size, data, size); - u64 ptr = page[0]->size; - page[0]->size += size; - return ptr; -} - -void *arena_alloc(arena_t *arena, u64 size) -{ - if (!arena) - return NULL; - else if (!arena->start) - { - arena->start = page_create(1); - arena->end = arena->start; - } - - page_t *best_fit; - for (best_fit = arena->start; best_fit; best_fit = best_fit->next) - if (best_fit->size + size + MEMORY_ALIGNMENT < best_fit->capacity) - break; - - if (!best_fit) - { - best_fit = page_create(size); - arena->end->next = best_fit; - arena->end = best_fit; - } - - // NOTE: Fsanitize has a hissy fit if we don't align memory "correctly" - u64 offset = 0; - - if (size % MEMORY_ALIGNMENT == 0) - { - u64 div = (((u64)(best_fit->data + best_fit->size)) % MEMORY_ALIGNMENT); - if (div != 0) - offset = MEMORY_ALIGNMENT - div; - } - - void *start = best_fit->data + best_fit->size + offset; - - best_fit->size += size + offset; - - return start; -} - -void *arena_realloc(arena_t *arena, void *ptr, u64 oldsize, u64 newsize) -{ - if (!ptr) - return arena_alloc(arena, newsize); - else if (!arena || !arena->start) - return NULL; - else if (newsize <= oldsize) - // No need to change anything. - return ptr; - - bool copy_into_new = true; - void *start = NULL; - page_t *old_page = NULL, *best_fit = NULL; - - for (page_t *page = arena->start; page; page = page->next) - { - if (!best_fit && page->size + newsize < page->capacity) - best_fit = page; - if (page->data <= (u8 *)ptr && - (u8 *)(ptr) + oldsize <= page->data + page->capacity) - old_page = page; - } - - // If the old page exists, ptr is the latest allocation in it, and it has - // enough space to contain the new size, just resize and return. - if (old_page && old_page->data + old_page->size - oldsize == ptr && - old_page->size - oldsize + newsize < old_page->capacity) - { - start = ptr; - old_page->size += newsize - oldsize; - copy_into_new = false; - } - else - { - if (!old_page) - copy_into_new = false; - if (!best_fit) - { - best_fit = page_create(newsize); - arena->end->next = best_fit; - arena->end = best_fit; - } - - start = best_fit->data + best_fit->size; - best_fit->size += newsize; - } - - if (copy_into_new) - { - memcpy(start, ptr, oldsize); - memset(start + oldsize, 0, newsize - oldsize); - } - - return start; -} - -void arena_attach(arena_t *arena, page_t *page) -{ - if (!arena || !page) - return; - else if (!arena->start || !arena->end) - { - arena->start = page; - arena->end = page; - } - else - { - page->next = arena->start; - arena->start = page; - } -} - -void arena_reset(arena_t *arena) -{ - if (!arena || !arena->start) - return; - - for (page_t *cur = arena->start; cur; cur = cur->next) - { - if (cur->size == 0) - continue; - cur->size = 0; - memset(cur->data, 0, cur->capacity); - } -} - -void arena_cleanup(arena_t *arena) -{ - if (!arena || !arena->start) - return; - - for (page_t *cur = arena->start, *next = NULL; cur; - next = cur->next, free(cur), cur = next) - continue; - - memset(arena, 0, sizeof(*arena)); -} - -// Allocates against stable memory i.e. we can have pointers of this lying -// around without any fear of them being thrown away. -void *context_alloc(context_t *context, u64 size) -{ - return arena_alloc(&context->memory, size); -} - -// Allocate against a "scratch space", separate from main memory, for internal -// use. -void *context_salloc(context_t *context, u64 size) -{ - return arena_alloc(&context->scratch, size); -} - -void context_reset_read(context_t *context) -{ - arena_reset(&context->read); -} - -void context_reset_scratch(context_t *context) -{ - arena_reset(&context->scratch); -} - -void context_reset(context_t *context) -{ - arena_reset(&context->memory); - arena_reset(&context->read); - arena_reset(&context->scratch); -} - -void context_cleanup(context_t *context) -{ - if (!context) - return; - arena_cleanup(&context->memory); - arena_cleanup(&context->read); - arena_cleanup(&context->scratch); - memset(context, 0, sizeof(*context)); -} - -void context_report(context_t *context) -{ -#if DEBUG - // Figure this out at runtime - u64 mem_used = 0, mem_cap = 0; - for (page_t *page = context->memory.start; page; page = page->next) - { - mem_used += page->size; - mem_cap += page->capacity; - } - - u64 read_used = 0, read_cap = 0; - for (page_t *page = context->read.start; page; page = page->next) - { - read_used += page->size; - read_cap += page->capacity; - } - - u64 scr_used = 0, scr_cap = 0; - for (page_t *page = context->scratch.start; page; page = page->next) - { - scr_used += page->size; - scr_cap += page->capacity; - } - - info("<Context>: %luB/%luB main memory used\n", mem_used, mem_cap); - info("<Context>: %luB/%luB read space used\n", read_used, read_cap); - info("<Context>: %luB/%luB scratch space used\n", scr_used, scr_cap); -#endif -} |