4 * Very simple linked-list based malloc()/free().
10 struct free_arena_header __malloc_head = {
21 /* This is extern so it can be overridden by the user application */
22 const size_t __stack_size = 4096;
24 static inline size_t sp(void)
27 asm volatile ("movl %%esp,%0":"=rm" (sp));
31 extern void *__mem_end;
33 void __init_memory_arena(void)
35 struct free_arena_header *fp;
36 size_t start, total_space;
38 start = (size_t) ARENA_ALIGN_UP(__mem_end);
39 total_space = sp() - start;
41 fp = (struct free_arena_header *)start;
42 fp->a.type = ARENA_TYPE_FREE;
43 fp->a.size = total_space - __stack_size;
45 /* Insert into chains */
46 fp->a.next = fp->a.prev = &__malloc_head;
47 fp->next_free = fp->prev_free = &__malloc_head;
48 __malloc_head.a.next = __malloc_head.a.prev = fp;
49 __malloc_head.next_free = __malloc_head.prev_free = fp;
52 static void *__malloc_from_block(struct free_arena_header *fp, size_t size)
55 struct free_arena_header *nfp, *na;
59 /* We need the 2* to account for the larger requirements of a free block */
60 if (fsize >= size + 2 * sizeof(struct arena_header)) {
61 /* Bigger block than required -- split block */
62 nfp = (struct free_arena_header *)((char *)fp + size);
65 nfp->a.type = ARENA_TYPE_FREE;
66 nfp->a.size = fsize - size;
67 fp->a.type = ARENA_TYPE_USED;
70 /* Insert into all-block chain */
76 /* Replace current block on free chain */
77 nfp->next_free = fp->next_free;
78 nfp->prev_free = fp->prev_free;
79 fp->next_free->prev_free = nfp;
80 fp->prev_free->next_free = nfp;
82 /* Allocate the whole block */
83 fp->a.type = ARENA_TYPE_USED;
85 /* Remove from free chain */
86 fp->next_free->prev_free = fp->prev_free;
87 fp->prev_free->next_free = fp->next_free;
90 return (void *)(&fp->a + 1);
93 void *malloc(size_t size)
95 struct free_arena_header *fp;
100 /* Add the obligatory arena header, and round up */
101 size = (size + 2 * sizeof(struct arena_header) - 1) & ~ARENA_SIZE_MASK;
103 for (fp = __malloc_head.next_free; fp->a.type != ARENA_TYPE_HEAD;
104 fp = fp->next_free) {
105 if (fp->a.size >= size) {
106 /* Found fit -- allocate out of this block */
107 return __malloc_from_block(fp, size);
111 /* Nothing found... need to request a block from the kernel */
112 return NULL; /* No kernel to get stuff from */