Home | History | Annotate | Download | only in dos
      1 /*
      2  * free.c
      3  *
      4  * Very simple linked-list based malloc()/free().
      5  */
      6 
      7 #include <stdlib.h>
      8 #include "malloc.h"
      9 
     10 static struct free_arena_header *__free_block(struct free_arena_header *ah)
     11 {
     12     struct free_arena_header *pah, *nah;
     13 
     14     pah = ah->a.prev;
     15     nah = ah->a.next;
     16     if (pah->a.type == ARENA_TYPE_FREE &&
     17 	(char *)pah + pah->a.size == (char *)ah) {
     18 	/* Coalesce into the previous block */
     19 	pah->a.size += ah->a.size;
     20 	pah->a.next = nah;
     21 	nah->a.prev = pah;
     22 
     23 #ifdef DEBUG_MALLOC
     24 	ah->a.type = ARENA_TYPE_DEAD;
     25 #endif
     26 
     27 	ah = pah;
     28 	pah = ah->a.prev;
     29     } else {
     30 	/* Need to add this block to the free chain */
     31 	ah->a.type = ARENA_TYPE_FREE;
     32 
     33 	ah->next_free = __malloc_head.next_free;
     34 	ah->prev_free = &__malloc_head;
     35 	__malloc_head.next_free = ah;
     36 	ah->next_free->prev_free = ah;
     37     }
     38 
     39     /* In either of the previous cases, we might be able to merge
     40        with the subsequent block... */
     41     if (nah->a.type == ARENA_TYPE_FREE &&
     42 	(char *)ah + ah->a.size == (char *)nah) {
     43 	ah->a.size += nah->a.size;
     44 
     45 	/* Remove the old block from the chains */
     46 	nah->next_free->prev_free = nah->prev_free;
     47 	nah->prev_free->next_free = nah->next_free;
     48 	ah->a.next = nah->a.next;
     49 	nah->a.next->a.prev = ah;
     50 
     51 #ifdef DEBUG_MALLOC
     52 	nah->a.type = ARENA_TYPE_DEAD;
     53 #endif
     54     }
     55 
     56     /* Return the block that contains the called block */
     57     return ah;
     58 }
     59 
     60 void free(void *ptr)
     61 {
     62     struct free_arena_header *ah;
     63 
     64     if (!ptr)
     65 	return;
     66 
     67     ah = (struct free_arena_header *)
     68 	((struct arena_header *)ptr - 1);
     69 
     70     __free_block(ah);
     71 
     72     /* Here we could insert code to return memory to the system. */
     73 }
     74