From 1b33861528041c0ba3f9b41f204e711424c4dce1 Mon Sep 17 00:00:00 2001 From: Georg Reinke Date: Tue, 28 Mar 2017 13:09:57 +0200 Subject: [PATCH] memtype-managed: correctly merge free blocks --- lib/memory.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/memory.c b/lib/memory.c index 1cde4c9ae..5e1ba2e99 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -181,8 +181,15 @@ int memory_managed_free(struct memtype *m, void *ptr, size_t len) // alignment, ptr may not actually be the start of the block if ((char*) block + sizeof(struct memblock) <= cptr && cptr < (char*) block + sizeof(struct memblock) + block->len) { - // try to merge it with a neighbouring free block - if (block->prev && !(block->prev->flags & MEMBLOCK_USED)) { + // try to merge it with neighbouring free blocks + if (block->prev && !(block->prev->flags & MEMBLOCK_USED) && + block->next && !(block->next->flags & MEMBLOCK_USED)) { + // special case first: both previous and next block are unused + block->prev->len += block->len + block->next->len + 2 * sizeof(struct memblock); + block->prev->next = block->next->next; + if (block->next->next) + block->next->next->prev = block->prev; + } else if (block->prev && !(block->prev->flags & MEMBLOCK_USED)) { block->prev->len += block->len + sizeof(struct memblock); block->prev->next = block->next; if (block->next)