summaryrefslogtreecommitdiffstats
path: root/contrib/syslinux-4.02/dos/free.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/syslinux-4.02/dos/free.c')
-rw-r--r--contrib/syslinux-4.02/dos/free.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/contrib/syslinux-4.02/dos/free.c b/contrib/syslinux-4.02/dos/free.c
new file mode 100644
index 0000000..020dc15
--- /dev/null
+++ b/contrib/syslinux-4.02/dos/free.c
@@ -0,0 +1,77 @@
+/*
+ * free.c
+ *
+ * Very simple linked-list based malloc()/free().
+ */
+
+#include <stdlib.h>
+#include "malloc.h"
+
+static struct free_arena_header *__free_block(struct free_arena_header *ah)
+{
+ struct free_arena_header *pah, *nah;
+
+ pah = ah->a.prev;
+ nah = ah->a.next;
+ if (pah->a.type == ARENA_TYPE_FREE &&
+ (char *)pah + pah->a.size == (char *)ah) {
+ /* Coalesce into the previous block */
+ pah->a.size += ah->a.size;
+ pah->a.next = nah;
+ nah->a.prev = pah;
+
+#ifdef DEBUG_MALLOC
+ ah->a.type = ARENA_TYPE_DEAD;
+#endif
+
+ ah = pah;
+ pah = ah->a.prev;
+ } else {
+ /* Need to add this block to the free chain */
+ ah->a.type = ARENA_TYPE_FREE;
+
+ ah->next_free = __malloc_head.next_free;
+ ah->prev_free = &__malloc_head;
+ __malloc_head.next_free = ah;
+ ah->next_free->prev_free = ah;
+ }
+
+ /* In either of the previous cases, we might be able to merge
+ with the subsequent block... */
+ if (nah->a.type == ARENA_TYPE_FREE &&
+ (char *)ah + ah->a.size == (char *)nah) {
+ ah->a.size += nah->a.size;
+
+ /* Remove the old block from the chains */
+ nah->next_free->prev_free = nah->prev_free;
+ nah->prev_free->next_free = nah->next_free;
+ ah->a.next = nah->a.next;
+ nah->a.next->a.prev = ah;
+
+#ifdef DEBUG_MALLOC
+ nah->a.type = ARENA_TYPE_DEAD;
+#endif
+ }
+
+ /* Return the block that contains the called block */
+ return ah;
+}
+
+void free(void *ptr)
+{
+ struct free_arena_header *ah;
+
+ if (!ptr)
+ return;
+
+ ah = (struct free_arena_header *)
+ ((struct arena_header *)ptr - 1);
+
+#ifdef DEBUG_MALLOC
+ assert(ah->a.type == ARENA_TYPE_USED);
+#endif
+
+ __free_block(ah);
+
+ /* Here we could insert code to return memory to the system. */
+}