4 * Very simple linked-list based malloc()/free().
13 static void *__malloc_from_block(struct free_arena_header
*fp
,
14 size_t size
, malloc_tag_t tag
)
17 struct free_arena_header
*nfp
, *na
;
18 unsigned int heap
= ARENA_HEAP_GET(fp
->a
.attrs
);
20 fsize
= ARENA_SIZE_GET(fp
->a
.attrs
);
22 /* We need the 2* to account for the larger requirements of a free block */
23 if ( fsize
>= size
+2*sizeof(struct arena_header
) ) {
24 /* Bigger block than required -- split block */
25 nfp
= (struct free_arena_header
*)((char *)fp
+ size
);
28 ARENA_TYPE_SET(nfp
->a
.attrs
, ARENA_TYPE_FREE
);
29 ARENA_HEAP_SET(nfp
->a
.attrs
, heap
);
30 ARENA_SIZE_SET(nfp
->a
.attrs
, fsize
-size
);
31 nfp
->a
.tag
= MALLOC_FREE
;
32 ARENA_TYPE_SET(fp
->a
.attrs
, ARENA_TYPE_USED
);
33 ARENA_SIZE_SET(fp
->a
.attrs
, size
);
36 /* Insert into all-block chain */
42 /* Replace current block on free chain */
43 nfp
->next_free
= fp
->next_free
;
44 nfp
->prev_free
= fp
->prev_free
;
45 fp
->next_free
->prev_free
= nfp
;
46 fp
->prev_free
->next_free
= nfp
;
48 /* Allocate the whole block */
49 ARENA_TYPE_SET(fp
->a
.attrs
, ARENA_TYPE_USED
);
52 /* Remove from free chain */
53 fp
->next_free
->prev_free
= fp
->prev_free
;
54 fp
->prev_free
->next_free
= fp
->next_free
;
57 return (void *)(&fp
->a
+ 1);
60 static void *_malloc(size_t size
, enum heap heap
, malloc_tag_t tag
)
62 struct free_arena_header
*fp
;
63 struct free_arena_header
*head
= &__malloc_head
[heap
];
66 dprintf("_malloc(%zu, %u, %u) @ %p = ",
67 size
, heap
, tag
, __builtin_return_address(0));
70 /* Add the obligatory arena header, and round up */
71 size
= (size
+ 2 * sizeof(struct arena_header
) - 1) & ARENA_SIZE_MASK
;
73 for ( fp
= head
->next_free
; fp
!= head
; fp
= fp
->next_free
) {
74 if ( ARENA_SIZE_GET(fp
->a
.attrs
) >= size
) {
75 /* Found fit -- allocate out of this block */
76 p
= __malloc_from_block(fp
, size
, tag
);
86 void *malloc(size_t size
)
88 return _malloc(size
, HEAP_MAIN
, MALLOC_CORE
);
91 void *lmalloc(size_t size
)
93 return _malloc(size
, HEAP_LOWMEM
, MALLOC_CORE
);
96 void *pmapi_lmalloc(size_t size
)
98 return _malloc(size
, HEAP_LOWMEM
, MALLOC_MODULE
);