4 * Very simple linked-list based malloc()/free().
11 struct free_arena_header __malloc_head =
23 extern void *__mem_end; /* In argv.c */
25 void __init_memory_arena(void)
27 extern char __heap_end[];
28 struct free_arena_header *fp;
30 fp = (struct free_arena_header *)__mem_end;
31 fp->a.type = ARENA_TYPE_FREE;
32 fp->a.size = __heap_end - (char *)__mem_end;
34 /* Insert into chains */
35 fp->a.next = fp->a.prev = &__malloc_head;
36 fp->next_free = fp->prev_free = &__malloc_head;
37 __malloc_head.a.next = __malloc_head.a.prev = fp;
38 __malloc_head.next_free = __malloc_head.prev_free = fp;
41 static void *__malloc_from_block(struct free_arena_header *fp, size_t size)
44 struct free_arena_header *nfp, *na;
48 /* We need the 2* to account for the larger requirements of a free block */
49 if ( fsize >= size+2*sizeof(struct arena_header) ) {
50 /* Bigger block than required -- split block */
51 nfp = (struct free_arena_header *)((char *)fp + size);
54 nfp->a.type = ARENA_TYPE_FREE;
55 nfp->a.size = fsize-size;
56 fp->a.type = ARENA_TYPE_USED;
59 /* Insert into all-block chain */
65 /* Replace current block on free chain */
66 nfp->next_free = fp->next_free;
67 nfp->prev_free = fp->prev_free;
68 fp->next_free->prev_free = nfp;
69 fp->prev_free->next_free = nfp;
71 /* Allocate the whole block */
72 fp->a.type = ARENA_TYPE_USED;
74 /* Remove from free chain */
75 fp->next_free->prev_free = fp->prev_free;
76 fp->prev_free->next_free = fp->next_free;
79 return (void *)(&fp->a + 1);
82 void *malloc(size_t size)
84 struct free_arena_header *fp;
89 /* Add the obligatory arena header, and round up */
90 size = (size+2*sizeof(struct arena_header)-1) & ~ARENA_SIZE_MASK;
92 for ( fp = __malloc_head.next_free ; fp->a.type != ARENA_TYPE_HEAD ;
93 fp = fp->next_free ) {
94 if ( fp->a.size >= size ) {
95 /* Found fit -- allocate out of this block */
96 return __malloc_from_block(fp, size);
100 /* Nothing found... need to request a block from the kernel */
101 return NULL; /* No kernel to get stuff from */
104 void *calloc(size_t nmemb, size_t size)