3 #include "allocator3.h"
6 typedef struct cacao_freeblock_t {
8 struct cacao_freeblock_t* next;
9 struct cacao_freeblock_t* prev; /* now a double-linked list */
10 } *cacao_freeblock_ptr_t;
12 static cacao_freeblock_ptr_t first = NULL;
13 static cacao_freeblock_ptr_t last = NULL;
19 void allocator_close()
23 void allocator_reset()
27 void* allocator_alloc(cacao_size_t size)
30 cacao_freeblock_ptr_t curr = first;
33 cacao_size_t curr_size = curr->size & ~0x3;
35 if (curr_size > size) {
37 cacao_freeblock_ptr_t next = curr + size;
38 cacao_size_t new_size = curr_size - size;
40 if (new_size >= sizeof(cacao_freeblock_ptr_t)) {
42 next->size = new_size | 0x3;
43 next->next = curr->next;
48 next->size = curr->size - size | 0x1;
52 if (curr->size == size) {
53 curr->prev->next = curr->next;
54 curr->next->prev = curr->prev;
62 void allocator_free_block(cacao_ptr_t block_addr, cacao_size_t size)
64 cacao_freeblock_ptr_t freeblock = (cacao_freeblock_ptr_t)block_addr;
66 /* reject small free blocks */
67 if (size < sizeof(struct cacao_freeblock_t))
70 /* store size in freeblock & flag it as free (2 least sign. bits) */
71 freeblock->size = size | 0x3;
73 freeblock->next = NULL;
74 freeblock->prev = last;
76 last->next = freeblock;
84 void allocator_free_prejoin (cacao_ptr_t block_addr, cacao_ptr_t pre_addr, cacao_size_t pre_size)
86 cacao_freeblock_ptr_t freeblock = (cacao_freeblock_ptr_t)block_addr;
87 cacao_freeblock_ptr_t preblock = (cacao_freeblock_ptr_t)pre_addr;
89 preblock->size = freeblock->size + pre_size;
90 preblock->next = freeblock->next;
91 preblock->prev = freeblock->prev;
94 preblock->next->prev = preblock;
96 preblock->prev->next = preblock;
99 void allocator_free_postjoin(cacao_ptr_t block_addr, cacao_ptr_t post_addr, cacao_size_t post_size)
101 cacao_freeblock_ptr_t freeblock = (cacao_freeblock_ptr_t)block_addr;
103 freeblock->size += post_size;
106 void allocator_free_blockjoin (cacao_ptr_t first_addr, cacao_ptr_t last_addr, cacao_size_t extra_size)
108 cacao_freeblock_ptr_t freeblock = (cacao_freeblock_ptr_t)first_addr;
109 cacao_freeblock_ptr_t endblock = (cacao_freeblock_ptr_t)end_addr;
111 freeblock->size += (endblock->size & ~0x3) + extra_size;
114 endblock->next->prev = endblock->prev;
116 endblock->prev->next = endblock->next;