Implemented Scratchpad_ReserveAligned and refactored internally

This commit is contained in:
VegOwOtenks 2024-10-01 21:37:05 +02:00
parent 7d8ba6fc28
commit c2c3c2d96e
2 changed files with 52 additions and 18 deletions

View file

@ -30,6 +30,32 @@ static void* _Scratchpad_ReserveHere(Scratchpad* pad, size_t size)
return scratch_buffer; 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) void* Scratchpad_Reserve(Scratchpad* pad, size_t size)
{ {
if (pad == NULL) return NULL; if (pad == NULL) return NULL;
@ -42,29 +68,36 @@ void* Scratchpad_Reserve(Scratchpad* pad, size_t size)
} }
if (reserve == NULL) { if (reserve == NULL) {
Scratchpad* new = Allocator_Allocate(pad->allocator, sizeof(*pad)); if (_Scratchpad_CreateEmbedded(pad, size)) return NULL;
if (new != NULL) { reserve = _Scratchpad_ReserveHere(pad, size);
// 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;
}
}
} }
return reserve; 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) int Scratchpad_Reclaim(Scratchpad* pad, void* pointer, size_t length)
{ {
if (pad == NULL) return EDESTADDRREQ; if (pad == NULL) return EDESTADDRREQ;

View file

@ -21,6 +21,7 @@ typedef struct Scratchpad_s {
int Scratchpad_Create(Scratchpad* target, size_t capacity, allocator_t* allocator); int Scratchpad_Create(Scratchpad* target, size_t capacity, allocator_t* allocator);
void* Scratchpad_Reserve(Scratchpad* pad, size_t size); 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); int Scratchpad_Reclaim(Scratchpad* pad, void* pointer, size_t length);
void Scratchpad_Reset(Scratchpad* pad); void Scratchpad_Reset(Scratchpad* pad);