Releasing debian version 4.06+dfsg-2.
[syslinux-debian/hramrach.git] / core / mem / malloc.c
blob78f7b41a72e11e3700614a1e5a0c4117927f0f82
1 /*
2 * malloc.c
4 * Very simple linked-list based malloc()/free().
5 */
7 #include <stdlib.h>
8 #include <errno.h>
9 #include <string.h>
10 #include <dprintf.h>
11 #include "malloc.h"
13 static void *__malloc_from_block(struct free_arena_header *fp,
14 size_t size, malloc_tag_t tag)
16 size_t fsize;
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);
26 na = fp->a.next;
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);
34 fp->a.tag = tag;
36 /* Insert into all-block chain */
37 nfp->a.prev = fp;
38 nfp->a.next = na;
39 na->a.prev = nfp;
40 fp->a.next = nfp;
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;
47 } else {
48 /* Allocate the whole block */
49 ARENA_TYPE_SET(fp->a.attrs, ARENA_TYPE_USED);
50 fp->a.tag = tag;
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];
64 void *p = NULL;
66 dprintf("_malloc(%zu, %u, %u) @ %p = ",
67 size, heap, tag, __builtin_return_address(0));
69 if (size) {
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);
77 break;
82 dprintf("%p\n", p);
83 return p;
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);