mirror of
https://github.com/raysan5/raylib.git
synced 2025-10-10 11:56:27 +00:00
Removing '__RemoveNode' (#935)
Replaced '__RemoveNode' as it was causing invalid memory accesses with regular doubly linked list deletion algorithm. Replaced double pointer iterator in 'MemPoolAlloc' with single pointer iterator. Fixed undefined variables errors in 'MemPoolFree' for the freelist bucket.
This commit is contained in:
54
src/rmem.h
54
src/rmem.h
@@ -168,21 +168,6 @@ static inline size_t __AlignSize(const size_t size, const size_t align)
|
|||||||
return (size + (align - 1)) & -align;
|
return (size + (align - 1)) & -align;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __RemoveNode(MemPool *const mempool, MemNode **const node)
|
|
||||||
{
|
|
||||||
if ((*node)->next != NULL) (*node)->next->prev = (*node)->prev;
|
|
||||||
else {
|
|
||||||
mempool->freeList.tail = (*node)->prev;
|
|
||||||
if (mempool->freeList.tail != NULL) mempool->freeList.tail->next = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*node)->prev != NULL) (*node)->prev->next = (*node)->next;
|
|
||||||
else {
|
|
||||||
mempool->freeList.head = (*node)->next;
|
|
||||||
if (mempool->freeList.head != NULL) mempool->freeList.head->prev = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Functions Definition - Memory Pool
|
// Module Functions Definition - Memory Pool
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@@ -244,6 +229,7 @@ void *MemPoolAlloc(MemPool *const mempool, const size_t size)
|
|||||||
const size_t ALLOC_SIZE = __AlignSize(size + sizeof *new_mem, sizeof(intptr_t));
|
const size_t ALLOC_SIZE = __AlignSize(size + sizeof *new_mem, sizeof(intptr_t));
|
||||||
const size_t BUCKET_INDEX = (ALLOC_SIZE >> MEMPOOL_BUCKET_BITS) - 1;
|
const size_t BUCKET_INDEX = (ALLOC_SIZE >> MEMPOOL_BUCKET_BITS) - 1;
|
||||||
|
|
||||||
|
// If the size is small enough, let's check if our buckets has a fitting memory block.
|
||||||
if (BUCKET_INDEX < MEMPOOL_BUCKET_SIZE && mempool->buckets[BUCKET_INDEX] != NULL && mempool->buckets[BUCKET_INDEX]->size >= ALLOC_SIZE)
|
if (BUCKET_INDEX < MEMPOOL_BUCKET_SIZE && mempool->buckets[BUCKET_INDEX] != NULL && mempool->buckets[BUCKET_INDEX]->size >= ALLOC_SIZE)
|
||||||
{
|
{
|
||||||
new_mem = mempool->buckets[BUCKET_INDEX];
|
new_mem = mempool->buckets[BUCKET_INDEX];
|
||||||
@@ -256,22 +242,28 @@ void *MemPoolAlloc(MemPool *const mempool, const size_t size)
|
|||||||
const size_t MEM_SPLIT_THRESHOLD = 16;
|
const size_t MEM_SPLIT_THRESHOLD = 16;
|
||||||
|
|
||||||
// If the freelist is valid, let's allocate FROM the freelist then!
|
// If the freelist is valid, let's allocate FROM the freelist then!
|
||||||
for (MemNode **inode = &mempool->freeList.head; *inode != NULL; inode = &(*inode)->next)
|
for (MemNode *inode = mempool->freeList.head; inode != NULL; inode = inode->next)
|
||||||
{
|
{
|
||||||
if ((*inode)->size < ALLOC_SIZE) continue;
|
if (inode->size < ALLOC_SIZE) continue;
|
||||||
else if ((*inode)->size <= (ALLOC_SIZE + MEM_SPLIT_THRESHOLD))
|
else if (inode->size <= (ALLOC_SIZE + MEM_SPLIT_THRESHOLD))
|
||||||
{
|
{
|
||||||
// Close in size - reduce fragmentation by not splitting.
|
// Close in size - reduce fragmentation by not splitting.
|
||||||
new_mem = *inode;
|
new_mem = inode;
|
||||||
__RemoveNode(mempool, inode);
|
(inode->prev != NULL)? (inode->prev->next = inode->next) : (mempool->freeList.head = inode->next);
|
||||||
|
(inode->next != NULL)? (inode->next->prev = inode->prev) : (mempool->freeList.tail = inode->prev);
|
||||||
|
|
||||||
|
if (mempool->freeList.head != NULL) mempool->freeList.head->prev = NULL;
|
||||||
|
else mempool->freeList.tail = NULL;
|
||||||
|
|
||||||
|
if (mempool->freeList.tail != NULL) mempool->freeList.tail->next = NULL;
|
||||||
mempool->freeList.len--;
|
mempool->freeList.len--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Split the memory chunk.
|
// Split the memory chunk.
|
||||||
new_mem = (MemNode *)((uint8_t *)*inode + ((*inode)->size - ALLOC_SIZE));
|
new_mem = (MemNode *)((uint8_t *)inode + (inode->size - ALLOC_SIZE));
|
||||||
(*inode)->size -= ALLOC_SIZE;
|
inode->size -= ALLOC_SIZE;
|
||||||
new_mem->size = ALLOC_SIZE;
|
new_mem->size = ALLOC_SIZE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -356,13 +348,13 @@ void MemPoolFree(MemPool *const restrict mempool, void *ptr)
|
|||||||
// attempted stack merge failed, try to place it into the memnode buckets
|
// attempted stack merge failed, try to place it into the memnode buckets
|
||||||
else if (BUCKET_INDEX < MEMPOOL_BUCKET_SIZE)
|
else if (BUCKET_INDEX < MEMPOOL_BUCKET_SIZE)
|
||||||
{
|
{
|
||||||
if (mempool->buckets[index] == NULL) mempool->buckets[index] = node;
|
if (mempool->buckets[BUCKET_INDEX] == NULL) mempool->buckets[BUCKET_INDEX] = mem_node;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (MemNode *n = mempool->buckets[index]; n != NULL; n = n->next) if( n==node ) return;
|
for (MemNode *n = mempool->buckets[BUCKET_INDEX]; n != NULL; n = n->next) if( n==mem_node ) return;
|
||||||
mempool->buckets[index]->prev = node;
|
mempool->buckets[BUCKET_INDEX]->prev = mem_node;
|
||||||
node->next = mempool->buckets[index];
|
mem_node->next = mempool->buckets[BUCKET_INDEX];
|
||||||
mempool->buckets[index] = node;
|
mempool->buckets[BUCKET_INDEX] = mem_node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Otherwise, we add it to the free list.
|
// Otherwise, we add it to the free list.
|
||||||
@@ -459,7 +451,13 @@ bool MemPoolDefrag(MemPool *const mempool)
|
|||||||
// If node is right at the stack, merge it back into the stack.
|
// If node is right at the stack, merge it back into the stack.
|
||||||
mempool->stack.base += (*node)->size;
|
mempool->stack.base += (*node)->size;
|
||||||
(*node)->size = 0UL;
|
(*node)->size = 0UL;
|
||||||
__RemoveNode(mempool, node);
|
((*node)->prev != NULL)? ((*node)->prev->next = (*node)->next) : (mempool->freeList.head = (*node)->next);
|
||||||
|
((*node)->next != NULL)? ((*node)->next->prev = (*node)->prev) : (mempool->freeList.tail = (*node)->prev);
|
||||||
|
|
||||||
|
if (mempool->freeList.head != NULL) mempool->freeList.head->prev = NULL;
|
||||||
|
else mempool->freeList.tail = NULL;
|
||||||
|
|
||||||
|
if (mempool->freeList.tail != NULL) mempool->freeList.tail->next = NULL;
|
||||||
mempool->freeList.len--;
|
mempool->freeList.len--;
|
||||||
node = &mempool->freeList.head;
|
node = &mempool->freeList.head;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user