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("movl %%esp,%0" : "=rm" (sp
));
32 extern void *__mem_end
;
34 void __init_memory_arena(void)
36 struct free_arena_header
*fp
;
37 size_t start
, total_space
;
39 start
= (size_t)ARENA_ALIGN_UP(__mem_end
);
40 total_space
= sp() - start
;
42 fp
= (struct free_arena_header
*)start
;
43 fp
->a
.type
= ARENA_TYPE_FREE
;
44 fp
->a
.size
= total_space
- __stack_size
;
46 /* Insert into chains */
47 fp
->a
.next
= fp
->a
.prev
= &__malloc_head
;
48 fp
->next_free
= fp
->prev_free
= &__malloc_head
;
49 __malloc_head
.a
.next
= __malloc_head
.a
.prev
= fp
;
50 __malloc_head
.next_free
= __malloc_head
.prev_free
= fp
;
53 static void *__malloc_from_block(struct free_arena_header
*fp
, size_t size
)
56 struct free_arena_header
*nfp
, *na
;
60 /* We need the 2* to account for the larger requirements of a free block */
61 if ( fsize
>= size
+2*sizeof(struct arena_header
) ) {
62 /* Bigger block than required -- split block */
63 nfp
= (struct free_arena_header
*)((char *)fp
+ size
);
66 nfp
->a
.type
= ARENA_TYPE_FREE
;
67 nfp
->a
.size
= fsize
-size
;
68 fp
->a
.type
= ARENA_TYPE_USED
;
71 /* Insert into all-block chain */
77 /* Replace current block on free chain */
78 nfp
->next_free
= fp
->next_free
;
79 nfp
->prev_free
= fp
->prev_free
;
80 fp
->next_free
->prev_free
= nfp
;
81 fp
->prev_free
->next_free
= nfp
;
83 /* Allocate the whole block */
84 fp
->a
.type
= ARENA_TYPE_USED
;
86 /* Remove from free chain */
87 fp
->next_free
->prev_free
= fp
->prev_free
;
88 fp
->prev_free
->next_free
= fp
->next_free
;
91 return (void *)(&fp
->a
+ 1);
94 void *malloc(size_t size
)
96 struct free_arena_header
*fp
;
101 /* Add the obligatory arena header, and round up */
102 size
= (size
+2*sizeof(struct arena_header
)-1) & ~ARENA_SIZE_MASK
;
104 for ( fp
= __malloc_head
.next_free
; fp
->a
.type
!= ARENA_TYPE_HEAD
;
105 fp
= fp
->next_free
) {
106 if ( fp
->a
.size
>= size
) {
107 /* Found fit -- allocate out of this block */
108 return __malloc_from_block(fp
, size
);
112 /* Nothing found... need to request a block from the kernel */
113 return NULL
; /* No kernel to get stuff from */