From d2882a68fe2e6f458ed756dc90c4474df5769c50 Mon Sep 17 00:00:00 2001 From: Kevin Yonan Date: Thu, 21 Nov 2019 16:27:23 -0700 Subject: [PATCH] Adding double ended stack & Mempool Reset function (#1021) --- src/rmem.h | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 118 insertions(+), 6 deletions(-) diff --git a/src/rmem.h b/src/rmem.h index 46e3b653..9c7d0a70 100644 --- a/src/rmem.h +++ b/src/rmem.h @@ -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