diff options
author | Stefan Bucur <stefan@stefan-mac.(none)> | 2009-07-03 23:29:23 +0300 |
---|---|---|
committer | Stefan Bucur <stefan@stefan-mac.(none)> | 2009-07-03 23:29:23 +0300 |
commit | c9d910a68845661946d1e040faaa4f46076fd64f (patch) | |
tree | 3ddbe48b4c7e17dbe91ec22ce9ccbc1bd467e8a0 /com32/lib/free.c | |
parent | 1ed097522de8d624905efc180e2324acb485e809 (diff) | |
download | syslinux-elf-c9d910a68845661946d1e040faaa4f46076fd64f.tar.gz syslinux-elf-c9d910a68845661946d1e040faaa4f46076fd64f.tar.xz syslinux-elf-c9d910a68845661946d1e040faaa4f46076fd64f.zip |
Fixed a merge issue with the previous commit
Diffstat (limited to 'com32/lib/free.c')
-rw-r--r-- | com32/lib/free.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/com32/lib/free.c b/com32/lib/free.c index f8a2e1f4..a91ad8ef 100644 --- a/com32/lib/free.c +++ b/com32/lib/free.c @@ -79,6 +79,43 @@ void free(void *ptr) /* Here we could insert code to return memory to the system. */ } +/* + * This is used to insert a block which is not previously on the + * free list. Only the a.size field of the arena header is assumed + * to be valid. + */ +void __inject_free_block(struct free_arena_header *ah) +{ + struct free_arena_header *nah; + size_t a_end = (size_t) ah + ARENA_SIZE_GET(ah->a.attrs); + size_t n_end; + + for (nah = __malloc_head.a.next; ARENA_TYPE_GET(nah->a.attrs) != ARENA_TYPE_HEAD; + nah = nah->a.next) { + n_end = (size_t) nah + ARENA_SIZE_GET(nah->a.attrs); + + /* Is nah entirely beyond this block? */ + if ((size_t) nah >= a_end) + break; + + /* Is this block entirely beyond nah? */ + if ((size_t) ah >= n_end) + continue; + + /* Otherwise we have some sort of overlap - reject this block */ + return; + } + + /* Now, nah should point to the successor block */ + ah->a.next = nah; + ah->a.prev = nah->a.prev; + nah->a.prev = ah; + ah->a.prev->a.next = ah; + + __free_block(ah); +} + + void __free_tagged(void *tag) { struct free_arena_header *fp, *nfp; |