| 22 | mem_node free_memory_root = {}; |
| 23 | |
| 24 | void *mymalloc(size_t size) { |
| 25 | // Static init at program startup: |
| 26 | if (!arena_end) { |
| 27 | arena_end = (uintptr_t)sbrk(0); |
| 28 | assert(arena_end != (uintptr_t)-1); |
| 29 | } |
| 30 | |
| 31 | // Find if there is an existing node we can reuse. |
| 32 | mem_node *prev = &free_memory_root; |
| 33 | mem_node *n = prev->next; |
| 34 | while (n) { |
| 35 | if (n->size >= size) { |
| 36 | prev->next = n->next; // Splice this node off from the free list. |
| 37 | return (void*)((uintptr_t)n + sizeof(mem_node)); |
| 38 | } |
| 39 | prev = n; |
| 40 | n = n->next; |
| 41 | } |
| 42 | |
| 43 | // If not, allocate new node from empty area |
| 44 | size_t allocated_size = sizeof(mem_node) + size; |
| 45 | |
| 46 | #if TEST_BRK // test brk() |
| 47 | uintptr_t new_brk = arena_end + allocated_size; |
| 48 | int failed = brk((void*)new_brk); |
| 49 | if (failed) return 0; |
| 50 | |
| 51 | mem_node *node = (mem_node*)arena_end; |
| 52 | arena_end = (uintptr_t)sbrk(0); |
| 53 | assert(arena_end == new_brk); |
| 54 | #else // test sbrk() |
| 55 | mem_node *node = (mem_node*)sbrk(allocated_size); |
| 56 | if ((uintptr_t)node == (uintptr_t)-1) |
| 57 | return 0; |
| 58 | #endif |
| 59 | node->size = size; |
| 60 | return (void*)((uintptr_t)node + sizeof(mem_node)); |
| 61 | } |
| 62 | |
| 63 | void myfree(void *ptr) { |
| 64 | mem_node *freed_node = (mem_node*)((uintptr_t)ptr - sizeof(mem_node)); |