* Implemented deleting completely empty chunks.
* Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39598 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -71,7 +71,7 @@ ClientMemoryAllocator::InitCheck()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *
|
void*
|
||||||
ClientMemoryAllocator::Allocate(size_t size, void** _address, bool& newArea)
|
ClientMemoryAllocator::Allocate(size_t size, void** _address, bool& newArea)
|
||||||
{
|
{
|
||||||
// Search best matching free block from the list
|
// Search best matching free block from the list
|
||||||
@@ -124,7 +124,7 @@ ClientMemoryAllocator::Allocate(size_t size, void** _address, bool& newArea)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ClientMemoryAllocator::Free(void *cookie)
|
ClientMemoryAllocator::Free(void* cookie)
|
||||||
{
|
{
|
||||||
if (cookie == NULL)
|
if (cookie == NULL)
|
||||||
return;
|
return;
|
||||||
@@ -136,13 +136,12 @@ ClientMemoryAllocator::Free(void *cookie)
|
|||||||
block_iterator iterator = fFreeBlocks.GetIterator();
|
block_iterator iterator = fFreeBlocks.GetIterator();
|
||||||
struct block* before = NULL;
|
struct block* before = NULL;
|
||||||
struct block* after = NULL;
|
struct block* after = NULL;
|
||||||
struct block* block;
|
|
||||||
|
|
||||||
// TODO: this could be done better if free blocks are sorted,
|
// TODO: this could be done better if free blocks are sorted,
|
||||||
// and if we had one free blocks list per chunk!
|
// and if we had one free blocks list per chunk!
|
||||||
// IOW this is a bit slow...
|
// IOW this is a bit slow...
|
||||||
|
|
||||||
while ((block = iterator.Next()) != NULL) {
|
while (struct block* block = iterator.Next()) {
|
||||||
if (block->chunk != freeBlock->chunk)
|
if (block->chunk != freeBlock->chunk)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -159,17 +158,30 @@ ClientMemoryAllocator::Free(void *cookie)
|
|||||||
fFreeBlocks.Remove(after);
|
fFreeBlocks.Remove(after);
|
||||||
free(after);
|
free(after);
|
||||||
free(freeBlock);
|
free(freeBlock);
|
||||||
|
freeBlock = before;
|
||||||
} else if (before != NULL) {
|
} else if (before != NULL) {
|
||||||
before->size += freeBlock->size;
|
before->size += freeBlock->size;
|
||||||
free(freeBlock);
|
free(freeBlock);
|
||||||
|
freeBlock = before;
|
||||||
} else if (after != NULL) {
|
} else if (after != NULL) {
|
||||||
after->base -= freeBlock->size;
|
after->base -= freeBlock->size;
|
||||||
after->size += freeBlock->size;
|
after->size += freeBlock->size;
|
||||||
free(freeBlock);
|
free(freeBlock);
|
||||||
|
freeBlock = after;
|
||||||
} else
|
} else
|
||||||
fFreeBlocks.Add(freeBlock);
|
fFreeBlocks.Add(freeBlock);
|
||||||
|
|
||||||
// TODO: check if the whole chunk is free now (we could delete it then)
|
if (freeBlock->size == freeBlock->chunk->size) {
|
||||||
|
// We can delete the chunk now
|
||||||
|
struct chunk* chunk = freeBlock->chunk;
|
||||||
|
|
||||||
|
fFreeBlocks.Remove(freeBlock);
|
||||||
|
free(freeBlock);
|
||||||
|
|
||||||
|
fChunks.Remove(chunk);
|
||||||
|
delete_area(chunk->area);
|
||||||
|
free(chunk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -237,7 +249,7 @@ ClientMemoryAllocator::Dump()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct block *
|
struct block*
|
||||||
ClientMemoryAllocator::_AllocateChunk(size_t size, bool& newArea)
|
ClientMemoryAllocator::_AllocateChunk(size_t size, bool& newArea)
|
||||||
{
|
{
|
||||||
// round up to multiple of page size
|
// round up to multiple of page size
|
||||||
|
|||||||
Reference in New Issue
Block a user