4 * @brief Dynamic memory manager for heap. This design do not incorporate any\
5 * specific implementation of malloc family. The main purpose of this routines is to
6 * provide handy method to initialize & grow the heap as needed by upstream implementation.
8 * This is designed to be portable, so it can serve as syscalls to malloc/free in the c std lib.
13 * @copyright Copyright (c) Lunaixsky 2022
17 #include <lunaix/mm/dmm.h>
18 #include <lunaix/mm/vmm.h>
19 #include <lunaix/mm/page.h>
20 #include <lunaix/status.h>
22 #include <lunaix/spike.h>
25 int _syscall_sbrk(void* addr) {
26 heap_context_t* uheap = &__current->mm.u_heap;
27 mutex_lock(&uheap->lock);
28 int r = lxsbrk(uheap, addr);
29 mutex_unlock(&uheap->lock);
33 void* _syscall_brk(size_t size) {
34 heap_context_t* uheap = &__current->mm.u_heap;
35 mutex_lock(&uheap->lock);
36 void* r = lxbrk(uheap, size);
37 mutex_unlock(&uheap->lock);
42 dmm_init(heap_context_t* heap)
44 assert((uintptr_t)heap->start % BOUNDARY == 0);
46 heap->brk = heap->start;
47 mutex_init(&heap->lock);
49 return vmm_alloc_page(__current->pid, heap->brk, NULL, PG_PREM_RW, 0) != NULL;
53 lxsbrk(heap_context_t* heap, void* addr)
55 return lxbrk(heap, addr - heap->brk) != NULL;
59 lxbrk(heap_context_t* heap, size_t size)
65 void* current_brk = heap->brk;
67 // The upper bound of our next brk of heap given the size.
68 // This will be used to calculate the page we need to allocate.
69 void* next = current_brk + ROUNDUP(size, BOUNDARY);
71 // any invalid situations
72 if (next >= heap->max_addr || next < current_brk) {
73 __current->k_status = LXINVLDPTR;
76 uintptr_t diff = PG_ALIGN(next) - PG_ALIGN(current_brk);
78 // if next do require new pages to be allocated
79 if (!vmm_alloc_pages(__current->pid, (void*)(PG_ALIGN(current_brk) + PG_SIZE),
82 __current->k_status = LXHEAPFULL;