summaryrefslogtreecommitdiff
path: root/com32/lib/realloc.c
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 /com32/lib/realloc.c
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.
Diffstat (limited to 'com32/lib/realloc.c')
-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;