From bc9902cf987b6849fc340b5c4c693798f7c6591e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 18 Mar 2006 18:37:37 +0000 Subject: [PATCH] Implemented freeing of blocks, though it's not very efficient yet. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16833 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/ClientMemoryAllocator.cpp | 42 ++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/servers/app/ClientMemoryAllocator.cpp b/src/servers/app/ClientMemoryAllocator.cpp index 7fac88dd11..f9371320e8 100644 --- a/src/servers/app/ClientMemoryAllocator.cpp +++ b/src/servers/app/ClientMemoryAllocator.cpp @@ -110,7 +110,47 @@ ClientMemoryAllocator::Free(void *cookie) if (cookie == NULL) return; - // TODO: implement me!!! + struct block* freeBlock = (struct block*)cookie; + + // search for an adjacent free block + + block_iterator iterator = fFreeBlocks.GetIterator(); + struct block* before = NULL; + struct block* after = NULL; + struct block* block; + + // TODO: this could be done better if free blocks are sorted, + // and if we had one free blocks list per chunk! + // IOW this is a bit slow... + + while ((block = iterator.Next()) != NULL) { + if (block->chunk != freeBlock->chunk) + continue; + + if (block->base + block->size == freeBlock->base) + before = block; + + if (block->base == freeBlock->base + freeBlock->size) + after = block; + } + + if (before != NULL && after != NULL) { + // merge with adjacent blocks + before->size += after->size + freeBlock->size; + fFreeBlocks.Remove(after); + free(after); + free(freeBlock); + } else if (before != NULL) { + before->size += freeBlock->size; + free(freeBlock); + } else if (after != NULL) { + after->base -= freeBlock->size; + after->size += freeBlock->size; + free(freeBlock); + } else + fFreeBlocks.Add(freeBlock); + + // TODO: check if the whole chunk is free now (we could delete it then) }