From f68fa9d36488b6c88e06d509cb9694ed03b4084a Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sun, 2 Nov 2008 02:59:15 +0000 Subject: [PATCH] Implemented realloc(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28454 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/runtime_loader/heap.cpp | 37 +++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/system/runtime_loader/heap.cpp b/src/system/runtime_loader/heap.cpp index f42ba8a185..03346a978e 100644 --- a/src/system/runtime_loader/heap.cpp +++ b/src/system/runtime_loader/heap.cpp @@ -24,7 +24,7 @@ static const size_t kInitialHeapSize = 65536; * linked list). * When memory is allocated, the smallest free chunk that contains * the requested size is split (or taken as a whole if it can't be - * splitted anymore), and it's lower half will be removed from the + * splitted anymore), and it's lower half will be removed from the * free list. * The free list is ordered by size, starting with the smallest * free chunk available. When a chunk is freed, it will be joint @@ -120,7 +120,7 @@ free_chunk::Join(free_chunk *chunk) } -void +void free_chunk::Remove(free_chunk *previous) { if (previous == NULL) { @@ -143,7 +143,7 @@ free_chunk::Remove(free_chunk *previous) } -void +void free_chunk::Enqueue() { free_chunk *chunk = sFreeAnchor.next, *last = &sFreeAnchor; @@ -237,10 +237,31 @@ dump_chunks(void) void * -realloc(void *buffer, size_t newSize) +realloc(void *allocation, size_t newSize) { - // not implemented - return NULL; + // free, if new size is 0 + if (newSize == 0) { + free(allocation); + return NULL; + } + + // just malloc(), if no previous allocation + if (allocation == NULL) + return malloc(newSize); + + // we're lazy and don't shrink allocations + free_chunk* chunk = free_chunk::SetToAllocated(allocation); + if (chunk->Size() >= newSize) + return allocation; + + // the allocation needs to grow -- allocate a new one and memcpy() + void* newAllocation = malloc(newSize); + if (newAllocation != NULL) { + memcpy(newAllocation, allocation, chunk->Size()); + free(allocation); + } + + return newAllocation; } @@ -322,7 +343,7 @@ free(void *allocated) // remove the joined chunk from the list last->next = freedChunk->next; chunk = last; - + if (++joinCount == 2) break; } @@ -331,7 +352,7 @@ free(void *allocated) chunk = chunk->next; } - // enqueue the link at the right position; the + // enqueue the link at the right position; the // free link queue is ordered by size freedChunk->Enqueue();