aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Yonan <assyrianic@users.noreply.github.com>2019-11-21 16:27:23 -0700
committerRay <raysan5@gmail.com>2019-11-22 00:27:23 +0100
commitd2882a68fe2e6f458ed756dc90c4474df5769c50 (patch)
tree5b2a5a20c87a5ad28c82ae8f94648b611f73c6c2
parent2ae5849826cb18aaf59ab24192ae43382e3ce1e2 (diff)
downloadraylib-d2882a68fe2e6f458ed756dc90c4474df5769c50.tar.gz
raylib-d2882a68fe2e6f458ed756dc90c4474df5769c50.zip
Adding double ended stack & Mempool Reset function (#1021)
-rw-r--r--src/rmem.h124
1 files 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