|
|
@ -93,6 +93,12 @@ typedef struct ObjPool { |
|
|
|
} ObjPool; |
|
|
|
|
|
|
|
|
|
|
|
// Double-Ended Stack aka Deque |
|
|
|
typedef struct BiStack { |
|
|
|
uint8_t *mem, *front, *back; |
|
|
|
size_t size; |
|
|
|
} BiStack; |
|
|
|
|
|
|
|
#if defined(__cplusplus) |
|
|
|
extern "C" { // Prevents name mangling of functions |
|
|
|
#endif |
|
|
@ -108,6 +114,7 @@ RMEMAPI void *MemPoolAlloc(MemPool *mempool, size_t bytes); |
|
|
|
RMEMAPI void *MemPoolRealloc(MemPool *mempool, void *ptr, size_t bytes); |
|
|
|
RMEMAPI void MemPoolFree(MemPool *mempool, void *ptr); |
|
|
|
RMEMAPI void MemPoolCleanUp(MemPool *mempool, void **ptrref); |
|
|
|
RMEMAPI void MemPoolReset(MemPool *mempool); |
|
|
|
RMEMAPI bool MemPoolDefrag(MemPool *mempool); |
|
|
|
|
|
|
|
RMEMAPI size_t GetMemPoolFreeMemory(const MemPool mempool); |
|
|
@ -124,6 +131,21 @@ RMEMAPI void *ObjPoolAlloc(ObjPool *objpool); |
|
|
|
RMEMAPI void ObjPoolFree(ObjPool *objpool, void *ptr); |
|
|
|
RMEMAPI void ObjPoolCleanUp(ObjPool *objpool, void **ptrref); |
|
|
|
|
|
|
|
//------------------------------------------------------------------------------------ |
|
|
|
// Functions Declaration - Double-Ended Stack |
|
|
|
//------------------------------------------------------------------------------------ |
|
|
|
RMEMAPI BiStack CreateBiStack(size_t len); |
|
|
|
RMEMAPI BiStack CreateBiStackFromBuffer(void *buf, size_t len); |
|
|
|
RMEMAPI void DestroyBiStack(BiStack *destack); |
|
|
|
|
|
|
|
RMEMAPI void *BiStackAllocFront(BiStack *destack, size_t len); |
|
|
|
RMEMAPI void *BiStackAllocBack(BiStack *destack, size_t len); |
|
|
|
|
|
|
|
RMEMAPI void BiStackResetFront(BiStack *destack); |
|
|
|
RMEMAPI void BiStackResetBack(BiStack *destack); |
|
|
|
RMEMAPI void BiStackResetAll(BiStack *destack); |
|
|
|
|
|
|
|
RMEMAPI intptr_t BiStackMargins(BiStack destack); |
|
|
|
|
|
|
|
#ifdef __cplusplus |
|
|
|
} |
|
|
@ -298,8 +320,7 @@ void *MemPoolAlloc(MemPool *const mempool, const size_t size) |
|
|
|
// -------------- |
|
|
|
new_mem->next = new_mem->prev = NULL; |
|
|
|
uint8_t *const final_mem = (uint8_t *)new_mem + sizeof *new_mem; |
|
|
|
memset(final_mem, 0, new_mem->size - sizeof *new_mem); |
|
|
|
return final_mem; |
|
|
|
return memset(final_mem, 0, new_mem->size - sizeof *new_mem); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -410,6 +431,15 @@ size_t GetMemPoolFreeMemory(const MemPool mempool) |
|
|
|
return total_remaining; |
|
|
|
} |
|
|
|
|
|
|
|
void MemPoolReset(MemPool *const mempool) |
|
|
|
{ |
|
|
|
if (mempool == NULL) return; |
|
|
|
mempool->freeList.head = mempool->freeList.tail = NULL; |
|
|
|
mempool->freeList.len = 0; |
|
|
|
for (size_t i = 0; i < MEMPOOL_BUCKET_SIZE; i++) mempool->buckets[i] = NULL; |
|
|
|
mempool->stack.base = mempool->stack.mem + mempool->stack.size; |
|
|
|
} |
|
|
|
|
|
|
|
bool MemPoolDefrag(MemPool *const mempool) |
|
|
|
{ |
|
|
|
if (mempool == NULL) return false; |
|
|
@ -418,10 +448,7 @@ bool MemPoolDefrag(MemPool *const mempool) |
|
|
|
// If the memory pool has been entirely released, fully defrag it. |
|
|
|
if (mempool->stack.size == GetMemPoolFreeMemory(*mempool)) |
|
|
|
{ |
|
|
|
mempool->freeList.head = mempool->freeList.tail = NULL; |
|
|
|
mempool->freeList.len = 0; |
|
|
|
for (size_t i = 0; i < MEMPOOL_BUCKET_SIZE; i++) mempool->buckets[i] = NULL; |
|
|
|
mempool->stack.base = mempool->stack.mem + mempool->stack.size; |
|
|
|
MemPoolReset(mempool); |
|
|
|
return true; |
|
|
|
} |
|
|
|
else |
|
|
@ -659,4 +686,89 @@ void ObjPoolCleanUp(ObjPool *const restrict objpool, void **ptrref) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------- |
|
|
|
// Module Functions Definition - Double-Ended Stack |
|
|
|
//---------------------------------------------------------------------------------- |
|
|
|
BiStack CreateBiStack(const size_t len) |
|
|
|
{ |
|
|
|
BiStack destack = { 0 }; |
|
|
|
if (len == 0UL) return destack; |
|
|
|
|
|
|
|
destack.size = len; |
|
|
|
destack.mem = malloc(len*sizeof *destack.mem); |
|
|
|
if (destack.mem==NULL) destack.size = 0UL; |
|
|
|
else |
|
|
|
{ |
|
|
|
destack.front = destack.mem; |
|
|
|
destack.back = destack.mem + len; |
|
|
|
} |
|
|
|
return destack; |
|
|
|
} |
|
|
|
|
|
|
|
BiStack CreateBiStackFromBuffer(void *const buf, const size_t len) |
|
|
|
{ |
|
|
|
BiStack destack = { 0 }; |
|
|
|
if (len == 0UL || buf == NULL) return destack; |
|
|
|
destack.size = len; |
|
|
|
destack.mem = destack.front = buf; |
|
|
|
destack.back = destack.mem + len; |
|
|
|
return destack; |
|
|
|
} |
|
|
|
|
|
|
|
void DestroyBiStack(BiStack *const destack) |
|
|
|
{ |
|
|
|
if ((destack == NULL) || (destack->mem == NULL)) return; |
|
|
|
free(destack->mem); |
|
|
|
*destack = (BiStack){0}; |
|
|
|
} |
|
|
|
|
|
|
|
void *BiStackAllocFront(BiStack *const destack, const size_t len) |
|
|
|
{ |
|
|
|
if ((destack == NULL) || (destack->mem == NULL)) return NULL; |
|
|
|
|
|
|
|
const size_t ALIGNED_LEN = __AlignSize(len, sizeof(uintptr_t)); |
|
|
|
// front end stack is too high! |
|
|
|
if (destack->front + ALIGNED_LEN >= destack->back) return NULL; |
|
|
|
|
|
|
|
uint8_t *ptr = destack->front; |
|
|
|
destack->front += ALIGNED_LEN; |
|
|
|
return ptr; |
|
|
|
} |
|
|
|
|
|
|
|
void *BiStackAllocBack(BiStack *const destack, const size_t len) |
|
|
|
{ |
|
|
|
if ((destack == NULL) || (destack->mem == NULL)) return NULL; |
|
|
|
|
|
|
|
const size_t ALIGNED_LEN = __AlignSize(len, sizeof(uintptr_t)); |
|
|
|
// back end stack is too low |
|
|
|
if (destack->back - ALIGNED_LEN <= destack->front) return NULL; |
|
|
|
|
|
|
|
destack->back -= ALIGNED_LEN; |
|
|
|
return destack->back; |
|
|
|
} |
|
|
|
|
|
|
|
void BiStackResetFront(BiStack *const destack) |
|
|
|
{ |
|
|
|
if ((destack == NULL) || (destack->mem == NULL)) return; |
|
|
|
destack->front = destack->mem; |
|
|
|
} |
|
|
|
|
|
|
|
void BiStackResetBack(BiStack *const destack) |
|
|
|
{ |
|
|
|
if ((destack == NULL) || (destack->mem == NULL)) return; |
|
|
|
destack->back = destack->mem + destack->size; |
|
|
|
} |
|
|
|
|
|
|
|
void BiStackResetAll(BiStack *const destack) |
|
|
|
{ |
|
|
|
BiStackResetBack(destack); |
|
|
|
BiStackResetFront(destack); |
|
|
|
} |
|
|
|
|
|
|
|
intptr_t BiStackMargins(const BiStack destack) |
|
|
|
{ |
|
|
|
return destack.back - destack.front; |
|
|
|
} |
|
|
|
|
|
|
|
#endif // RMEM_IMPLEMENTATION |