From c2c3c2d96e6296b439e901c89d868185cdc82960 Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Tue, 1 Oct 2024 21:37:05 +0200 Subject: [PATCH] Implemented Scratchpad_ReserveAligned and refactored internally --- src/Scratchpad/Scratchpad.c | 69 +++++++++++++++++++++++++++---------- src/Scratchpad/Scratchpad.h | 1 + 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/src/Scratchpad/Scratchpad.c b/src/Scratchpad/Scratchpad.c index 488e854..b905d59 100644 --- a/src/Scratchpad/Scratchpad.c +++ b/src/Scratchpad/Scratchpad.c @@ -30,6 +30,32 @@ static void* _Scratchpad_ReserveHere(Scratchpad* pad, size_t size) return scratch_buffer; } +static int _Scratchpad_CreateEmbedded(Scratchpad* pad, size_t size) +{ + Scratchpad* new = Allocator_Allocate(pad->allocator, sizeof(*pad)); + if (new != NULL) { + // Copy current pad in the *next pointer + memcpy(new, pad, sizeof(*pad)); + + // Calculate new capacity + size_t new_capacity = size > pad->capacity ? + pad->capacity * (size / pad->capacity + 1) + : pad->capacity; + + // Initialize new pad + if (Scratchpad_Create(pad, new_capacity, pad->allocator)) { + Allocator_Free(pad->allocator, new, sizeof(*new)); + return EXIT_FAILURE; + } else { + pad->next = new; + } + } else { + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + void* Scratchpad_Reserve(Scratchpad* pad, size_t size) { if (pad == NULL) return NULL; @@ -42,29 +68,36 @@ void* Scratchpad_Reserve(Scratchpad* pad, size_t size) } if (reserve == NULL) { - Scratchpad* new = Allocator_Allocate(pad->allocator, sizeof(*pad)); - if (new != NULL) { - // Copy current pad in the *next pointer - memcpy(new, pad, sizeof(*pad)); - - // Calculate new capacity - size_t new_capacity = size > pad->capacity ? - pad->capacity * (size / pad->capacity + 1) - : pad->capacity; - - // Initialize new pad - if (Scratchpad_Create(pad, new_capacity, pad->allocator)) { - Allocator_Free(pad->allocator, new, sizeof(*new)); - } else { - reserve = Scratchpad_Reserve(pad, size); - pad->next = new; - } - } + if (_Scratchpad_CreateEmbedded(pad, size)) return NULL; + reserve = _Scratchpad_ReserveHere(pad, size); } return reserve; } +void* Scratchpad_ReserveAligned(Scratchpad* pad, size_t amount, size_t alignment) +{ + if (pad == NULL) return NULL; + + if (alignment == 1) return Scratchpad_Reserve(pad, amount); + + Scratchpad* root = pad; + do { + uintptr_t pointer_value = (uintptr_t) pad->memory; + uintptr_t alignment_padding = alignment - (pointer_value % alignment); + void* memory = _Scratchpad_ReserveHere(pad, alignment_padding + amount); + if (memory != NULL) return memory; + + pad = pad->next; + + } while (pad != NULL); + + + if (_Scratchpad_CreateEmbedded(root, amount)) return NULL; + + return _Scratchpad_ReserveHere(root, amount); +} + int Scratchpad_Reclaim(Scratchpad* pad, void* pointer, size_t length) { if (pad == NULL) return EDESTADDRREQ; diff --git a/src/Scratchpad/Scratchpad.h b/src/Scratchpad/Scratchpad.h index 132b557..0ef9d4d 100644 --- a/src/Scratchpad/Scratchpad.h +++ b/src/Scratchpad/Scratchpad.h @@ -21,6 +21,7 @@ typedef struct Scratchpad_s { int Scratchpad_Create(Scratchpad* target, size_t capacity, allocator_t* allocator); void* Scratchpad_Reserve(Scratchpad* pad, size_t size); +void* Scratchpad_ReserveAligned(Scratchpad* pad, size_t amount, size_t alignment); int Scratchpad_Reclaim(Scratchpad* pad, void* pointer, size_t length); void Scratchpad_Reset(Scratchpad* pad);