4 * Very simple linked-list based malloc()/free().
10 struct free_arena_header __malloc_head =
22 /* This is extern so it can be overridden by the user application */
23 const size_t __stack_size = 4096;
25 static inline size_t sp(void)
28 asm volatile("movw %%sp,%0" : "=rm" (sp));
32 void __init_memory_arena(void)
34 extern char _end[]; /* Symbol created by the linker */
35 struct free_arena_header *fp;
36 size_t start, total_space;
38 start = (size_t)ARENA_ALIGN_UP(_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 */