Implemented Scratchpad_ReserveAligned and refactored internally
This commit is contained in:
parent
7d8ba6fc28
commit
c2c3c2d96e
2 changed files with 52 additions and 18 deletions
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue