aboutsummaryrefslogtreecommitdiffstats
path: root/com32/lib/free.c
diff options
context:
space:
mode:
authorStefan Bucur <stefan@stefan-mac.(none)>2009-07-03 23:29:23 +0300
committerStefan Bucur <stefan@stefan-mac.(none)>2009-07-03 23:29:23 +0300
commitc9d910a68845661946d1e040faaa4f46076fd64f (patch)
tree3ddbe48b4c7e17dbe91ec22ce9ccbc1bd467e8a0 /com32/lib/free.c
parent1ed097522de8d624905efc180e2324acb485e809 (diff)
downloadsyslinux-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.c37
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;