50#if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED)
51 #define RMEMAPI __declspec(dllexport)
52#elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED)
53 #define RMEMAPI __declspec(dllimport)
58#define RMEM_VERSION "v1.3"
110#if defined(__cplusplus)
167#if defined(RMEM_IMPLEMENTATION)
179#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__) || defined(_MSC_VER)
181 #define restrict __restrict
193static inline size_t __AlignSize(
const size_t size,
const size_t align)
195 return (size + (align - 1)) & -align;
198static MemNode *__SplitMemNode(
MemNode *
const node,
const size_t bytes)
219static void __ReplaceMemNode(
MemNode *
const old,
MemNode *
const replace)
255 if (node->
size < bytes)
continue;
258 else return __SplitMemNode(node, bytes);
263static void __InsertMemNode(
MemPool *
const mempool,
AllocList *
const list,
MemNode *
const node,
const bool is_bucket)
277 __RemoveMemNode(list, iter);
288 if (iter==node)
return;
289 else if (iter < node)
292 if (iter_end > inode)
return;
293 else if (iter_end==inode && !is_bucket)
296 iter->size += node->
size;
299 else if (iter->next ==
NULL)
308 else if (iter > node)
311 if (iiter < node_end)
return;
312 else if (iter==list->
head && !is_bucket)
314 if (iter_end==inode) iter->size += node->
size;
315 else if (node_end==iiter)
332 else if (iter_end==inode && !is_bucket)
335 iter->size += node->
size;
340 __InsertMemNodeBefore(list, node, iter);
357 if (size == 0)
return mempool;
361 uint8_t *
const restrict buf = malloc(size*
sizeof *buf);
362 if (buf==
NULL)
return mempool;
376 if ((size == 0) || (buf ==
NULL) || (size <=
sizeof(
MemNode)))
return mempool;
388 if (mempool->arena.mem == 0)
return;
391 void *
const restrict ptr = (
void* )mempool->arena.mem;
399 if ((size == 0) || (size > mempool->
arena.
size))
return NULL;
403 const size_t ALLOC_SIZE = __AlignSize(size +
sizeof *new_mem,
sizeof(
intptr_t));
409 new_mem = __FindMemNode(&mempool->
buckets[BUCKET_SLOT], ALLOC_SIZE);
413 new_mem = __FindMemNode(&mempool->
large, ALLOC_SIZE);
428 new_mem->
size = ALLOC_SIZE;
443 uint8_t *
const restrict final_mem = (
uint8_t* )new_mem +
sizeof *new_mem;
444 return memset(final_mem, 0, new_mem->
size -
sizeof *new_mem);
450 if (size > mempool->arena.size)
return NULL;
457 const size_t NODE_SIZE =
sizeof *node;
459 if (resized_block ==
NULL)
return NULL;
462 MemNode *
const resized = (
MemNode* )(resized_block -
sizeof *resized);
463 memmove(resized_block, ptr, (node->
size > resized->
size)? (resized->
size - NODE_SIZE) : (node->
size - NODE_SIZE));
465 return resized_block;
473 if ((ptr ==
NULL) || (p -
sizeof(
MemNode) < mempool->arena.mem))
return;
482 if ((block < mempool->arena.offs) ||
483 ((block - mempool->arena.mem) > mempool->arena.size) ||
484 (mem_node->size == 0) ||
485 (mem_node->size > mempool->arena.size))
return;
487 else if (block == mempool->arena.offs)
489 mempool->arena.offs += mem_node->
size;
502 if ((ptrref ==
NULL) || (*ptrref ==
NULL))
return;
518 return total_remaining;
540 if ((
len == 0) || (objsize == 0))
return objpool;
543 const size_t aligned_size = __AlignSize(objsize,
sizeof(
size_t));
544 uint8_t *
const restrict buf = calloc(
len, aligned_size);
545 if (buf ==
NULL)
return objpool;
546 objpool.
objSize = aligned_size;
552 size_t *
const restrict index = (
size_t* )(objpool.
mem + (i*aligned_size));
566 const size_t aligned_size = __AlignSize(objsize,
sizeof(
size_t));
567 if ((buf ==
NULL) || (
len == 0) || (objsize <
sizeof(
size_t)) || (objsize*
len != aligned_size*
len))
return objpool;
570 objpool.
objSize = aligned_size;
576 size_t *
const restrict index = (
size_t* )(objpool.
mem + (i*aligned_size));
587 if (objpool->mem == 0)
return;
590 void *
const restrict ptr = (
void* )objpool->mem;
603 size_t *
const restrict block = (
size_t* )objpool->
offs;
609 return memset(block, 0, objpool->
objSize);
617 if ((ptr ==
NULL) || (block < objpool->mem) || (block > objpool->mem + objpool->memSize*objpool->objSize))
return;
623 size_t *
const restrict index = (
size_t* )block;
624 *index = (objpool->offs != 0)? (objpool->offs - objpool->mem)/objpool->objSize : objpool->memSize;
625 objpool->offs = block;
626 objpool->freeBlocks++;
632 if (ptrref ==
NULL)
return;
647 if (
len == 0)
return destack;
650 if (buf==
NULL)
return destack;
661 if (
len == 0 || buf ==
NULL)
return destack;
673 if (destack->mem == 0)
return;
684 if (destack->mem == 0)
return NULL;
687 const size_t ALIGNED_LEN = __AlignSize(
len,
sizeof(
uintptr_t));
689 if (destack->front + ALIGNED_LEN >= destack->back)
return NULL;
693 destack->front += ALIGNED_LEN;
701 if (destack->mem == 0)
return NULL;
704 const size_t ALIGNED_LEN = __AlignSize(
len,
sizeof(
uintptr_t));
706 if (destack->back - ALIGNED_LEN <= destack->front)
return NULL;
709 destack->back -= ALIGNED_LEN;
718 if (destack->
mem == 0)
return;
724 if (destack->
mem == 0)
return;
RMEMAPI BiStack CreateBiStackFromBuffer(void *buf, size_t len)
RMEMAPI size_t GetMemPoolFreeMemory(const MemPool mempool)
RMEMAPI void DestroyObjPool(ObjPool *objpool)
RMEMAPI void * MemPoolAlloc(MemPool *mempool, size_t bytes)
RMEMAPI void * ObjPoolAlloc(ObjPool *objpool)
RMEMAPI void * MemPoolRealloc(MemPool *mempool, void *ptr, size_t bytes)
RMEMAPI BiStack CreateBiStack(size_t len)
RMEMAPI MemPool CreateMemPool(size_t bytes)
RMEMAPI void * BiStackAllocFront(BiStack *destack, size_t len)
RMEMAPI ObjPool CreateObjPool(size_t objsize, size_t len)
RMEMAPI void ObjPoolFree(ObjPool *objpool, void *ptr)
RMEMAPI void * BiStackAllocBack(BiStack *destack, size_t len)
RMEMAPI void ObjPoolCleanUp(ObjPool *objpool, void **ptrref)
#define RMEMAPI
rmem - raylib memory pool and objects pool
RMEMAPI ObjPool CreateObjPoolFromBuffer(void *buf, size_t objsize, size_t len)
RMEMAPI intptr_t BiStackMargins(BiStack destack)
RMEMAPI void MemPoolFree(MemPool *mempool, void *ptr)
RMEMAPI void MemPoolReset(MemPool *mempool)
RMEMAPI void BiStackResetBack(BiStack *destack)
RMEMAPI void MemPoolCleanUp(MemPool *mempool, void **ptrref)
RMEMAPI void DestroyMemPool(MemPool *mempool)
RMEMAPI void DestroyBiStack(BiStack *destack)
RMEMAPI MemPool CreateMemPoolFromBuffer(void *buf, size_t bytes)
RMEMAPI void BiStackResetFront(BiStack *destack)
RMEMAPI void BiStackResetAll(BiStack *destack)
_W64 unsigned int uintptr_t
AllocList buckets[MEMPOOL_BUCKET_SIZE]