Adding double ended stack & Mempool Reset function (#1021)

This commit is contained in:
Kevin Yonan 2019-11-21 16:27:23 -07:00 committed by Ray
parent 2ae5849826
commit d2882a68fe

View File

@ -93,6 +93,12 @@ typedef struct ObjPool {
} ObjPool; } ObjPool;
// Double-Ended Stack aka Deque
typedef struct BiStack {
uint8_t *mem, *front, *back;
size_t size;
} BiStack;
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { // Prevents name mangling of functions extern "C" { // Prevents name mangling of functions
#endif #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 *MemPoolRealloc(MemPool *mempool, void *ptr, size_t bytes);
RMEMAPI void MemPoolFree(MemPool *mempool, void *ptr); RMEMAPI void MemPoolFree(MemPool *mempool, void *ptr);
RMEMAPI void MemPoolCleanUp(MemPool *mempool, void **ptrref); RMEMAPI void MemPoolCleanUp(MemPool *mempool, void **ptrref);
RMEMAPI void MemPoolReset(MemPool *mempool);
RMEMAPI bool MemPoolDefrag(MemPool *mempool); RMEMAPI bool MemPoolDefrag(MemPool *mempool);
RMEMAPI size_t GetMemPoolFreeMemory(const 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 ObjPoolFree(ObjPool *objpool, void *ptr);
RMEMAPI void ObjPoolCleanUp(ObjPool *objpool, void **ptrref); 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 #ifdef __cplusplus
} }
@ -298,8 +320,7 @@ void *MemPoolAlloc(MemPool *const mempool, const size_t size)
// -------------- // --------------
new_mem->next = new_mem->prev = NULL; new_mem->next = new_mem->prev = NULL;
uint8_t *const final_mem = (uint8_t *)new_mem + sizeof *new_mem; uint8_t *const final_mem = (uint8_t *)new_mem + sizeof *new_mem;
memset(final_mem, 0, new_mem->size - sizeof *new_mem); return memset(final_mem, 0, new_mem->size - sizeof *new_mem);
return final_mem;
} }
} }
@ -410,6 +431,15 @@ size_t GetMemPoolFreeMemory(const MemPool mempool)
return total_remaining; 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) bool MemPoolDefrag(MemPool *const mempool)
{ {
if (mempool == NULL) return false; 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 the memory pool has been entirely released, fully defrag it.
if (mempool->stack.size == GetMemPoolFreeMemory(*mempool)) if (mempool->stack.size == GetMemPoolFreeMemory(*mempool))
{ {
mempool->freeList.head = mempool->freeList.tail = NULL; MemPoolReset(mempool);
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;
return true; return true;
} }
else 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 #endif // RMEM_IMPLEMENTATION