summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-02-21 18:17:49 -0800
committerH. Peter Anvin <hpa@zytor.com>2008-02-21 18:17:49 -0800
commit2b20b079f22f236eed97b920672f57821c5974ba (patch)
tree87842fb5e268aed2118e925c09fef07001bcd371
parentce6265e0c4577aa7871e337cec549b0d844706ce (diff)
downloadsyslinux-3.62-pre13.tar.gz
realloc(): try to protect a block in the path of a growing objectsyslinux-3.62-pre13
When we realloc() a block larger, try to protect the free block following it from being immediately allocated by something else by placing it at the end of the freelist instead of the beginning.
-rw-r--r--com32/lib/realloc.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/com32/lib/realloc.c b/com32/lib/realloc.c
index 802d973c..89b63c8e 100644
--- a/com32/lib/realloc.c
+++ b/com32/lib/realloc.c
@@ -65,10 +65,21 @@ void *realloc(void *ptr, size_t size)
nah->a.prev = ah;
/* Insert into free list */
- nah->next_free = __malloc_head.next_free;
- nah->prev_free = &__malloc_head;
- __malloc_head.next_free = nah;
- nah->next_free->prev_free = nah;
+ if (newsize > oldsize) {
+ /* Hack: this free block is in the path of a memory object
+ which has already been grown at least once. As such, put
+ it at the *end* of the freelist instead of the beginning;
+ trying to save it for future realloc()s of the same block. */
+ nah->prev_free = __malloc_head.prev_free;
+ nah->next_free = &__malloc_head;
+ __malloc_head.prev_free = nah;
+ nah->prev_free->next_free = nah;
+ } else {
+ nah->next_free = __malloc_head.next_free;
+ nah->prev_free = &__malloc_head;
+ __malloc_head.next_free = nah;
+ nah->next_free->prev_free = nah;
+ }
}
/* otherwise, use up the whole block */
return ptr;