22#include "irx_imports.h"
25#define MODNAME "alloc"
26IRX_ID(
"Basic alloc library", 1, 1);
30static vs32 alloc_sema = -1;
32#define DEFAULT_HEAP_SIZE 128 * 1024
34u32 heap_size = DEFAULT_HEAP_SIZE;
35static u8 * heap_start, * heap_end, * _heap_ptr;
37static void alloc_lock() {
38 if (alloc_sema >= 0) {
43static void alloc_unlock() {
44 if (alloc_sema >= 0) {
45 SignalSema(alloc_sema);
49int _start(
int argc,
char *argv[])
53 if (RegisterLibraryEntries(&_exp_alloc) != 0)
54 return MODULE_NO_RESIDENT_END;
58 heap_size = strtoul(argv[1], NULL, 0);
61 if (!(heap_start = AllocSysMemory(ALLOC_FIRST, heap_size, NULL)))
62 return MODULE_NO_RESIDENT_END;
63 heap_end = heap_start + heap_size;
64 _heap_ptr = heap_start;
71 alloc_sema = CreateSema(&sem_info);
73 return MODULE_RESIDENT_END;
79 if (alloc_sema >= 0) {
80 DeleteSema(alloc_sema);
83 FreeSysMemory(heap_start);
89#define DEFAULT_ALIGNMENT 16
92#define ALIGN(x, align) (((x)+((align)-1))&~((align)-1))
103static void * __alloc_heap_base = NULL;
107static void * alloc_sbrk(
size_t increment)
109 u8 *mp, *ret = (
void *)-1;
115 mp = _heap_ptr + increment;
116 if (mp <= heap_end) {
128 u32 prev_top, next_bot;
130 while (prev_mem != NULL) {
131 if (prev_mem->next != NULL) {
132 prev_top = (u32)prev_mem->ptr + prev_mem->size;
133 next_bot = (u32)prev_mem->next - prev_top;
134 if (next_bot >= size)
138 prev_mem = prev_mem->next;
144void * malloc(
size_t size)
146 void *ptr = NULL, *mem_ptr;
159 if (__alloc_heap_head == NULL) {
161 if (__alloc_heap_base == NULL) {
162 size_t heap_align_bytes;
165 alloc_sbrk(heap_align_bytes);
166 __alloc_heap_base = alloc_sbrk(0);
170 if ((mem_ptr = alloc_sbrk(mem_sz)) == (
void *)-1)
176 __alloc_heap_head->ptr = ptr;
178 __alloc_heap_head->prev = NULL;
179 __alloc_heap_head->next = NULL;
181 __alloc_heap_tail = __alloc_heap_head;
188 if ((
void *)((u8 *)__alloc_heap_base + mem_sz) < (
void *)__alloc_heap_head) {
194 new_mem->prev = NULL;
195 new_mem->next = __alloc_heap_head;
196 new_mem->next->prev = new_mem;
197 __alloc_heap_head = new_mem;
205 if (prev_mem != NULL) {
211 new_mem->prev = prev_mem;
212 new_mem->next = prev_mem->next;
213 new_mem->next->prev = new_mem;
214 prev_mem->next = new_mem;
222 if ((mem_ptr = alloc_sbrk(mem_sz)) == (
void *)-1) {
232 new_mem->prev = __alloc_heap_tail;
233 new_mem->next = NULL;
235 __alloc_heap_tail->next = new_mem;
236 __alloc_heap_tail = new_mem;
242void * realloc(
void *ptr,
size_t size)
245 void *new_ptr = NULL;
247 if (!size && ptr != NULL) {
264 if (prev_mem->size >= size) {
267 alloc_sbrk((u8 *)ptr + size - (u8 *)(alloc_sbrk(0)));
268 prev_mem->size = size;
278 if (!prev_mem->next) {
280 if (alloc_sbrk(size - prev_mem->size) == (
void*) -1)
282 prev_mem->size = size;
289 if ((
size_t)(prev_mem->next->ptr - ptr) > size) {
290 prev_mem->size = size;
299 if ((new_ptr = malloc(size)) == NULL)
303 memcpy(new_ptr, ptr, prev_mem->size);
309void * calloc(
size_t n,
size_t size)
312 size_t sz = n * size;
314 if ((ptr = malloc(sz)) == NULL)
321void * memalign(
size_t align,
size_t size)
333 if ((ptr = malloc(size + align)) == NULL)
337 if (((u32)ptr & (align - 1)) == 0)
342 cur_mem->size -= align;
345 ptr = (
void *)ALIGN((u32)ptr, align);
356 cur_mem->prev->next = cur_mem;
358 cur_mem->next->prev = cur_mem;
360 if (__alloc_heap_head == old_mem)
361 __alloc_heap_head = cur_mem;
363 if (__alloc_heap_tail == old_mem)
364 __alloc_heap_tail = cur_mem;
382 if (!__alloc_heap_head) {
389 if (ptr == __alloc_heap_head->ptr) {
390 size = __alloc_heap_head->size +
391 (size_t)(__alloc_heap_head->ptr - (
void *)__alloc_heap_head);
393 __alloc_heap_head = __alloc_heap_head->next;
395 if (__alloc_heap_head != NULL) {
396 __alloc_heap_head->prev = NULL;
398 __alloc_heap_tail = NULL;
407 cur = __alloc_heap_head;
408 while (ptr != cur->ptr) {
410 if (cur->next == NULL) {
419 if (cur->next != NULL) {
420 cur->next->prev = cur->prev;
425 __alloc_heap_tail = cur->prev;
429 heap_top = alloc_sbrk(0);
430 size = (u32)heap_top - (u32)((u8 *)(cur->prev->ptr) + cur->prev->size);
434 cur->prev->next = cur->next;
439void * __mem_walk_begin() {
440 return __alloc_heap_head;
443void __mem_walk_read(
void * token, u32 * size,
void ** ptr,
int * valid) {
452void * __mem_walk_inc(
void * token) {
458int __mem_walk_end(
void * token) {
459 return token == NULL;
#define DEFAULT_ALIGNMENT
static heap_mem_header_t * _heap_mem_fit(heap_mem_header_t *head, size_t size)