#include "liballoc.h" #include #include #include #include #include #include #include #define HEAP_REGION_SIZE 0x40000000 #define HEAP_EXPAND_INCREMENT 0x100000 void *heap_alloc(heap_t *heap, size_t sz) { return _lbmalloc(heap, sz); } void *heap_realloc(heap_t *heap, void *p, size_t sz) { return _lbrealloc(heap, p, sz); } void *heap_calloc(heap_t *heap, size_t num, size_t itemsz) { return _lbcalloc(heap, num, itemsz); } void heap_free(heap_t *heap, void *p) { _lbfree(heap, p); } static kern_status_t init_heap_region(heap_t *heap) { kern_handle_t self, address_space; task_self(&self); task_get_address_space(self, &address_space); kern_handle_close(self); kern_status_t status = vm_region_create( address_space, "libc-heap", 9, VM_REGION_ANY_OFFSET, HEAP_REGION_SIZE, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_USER, &heap->heap_region, &heap->heap_base); kern_handle_close(address_space); if (status != KERN_OK) { return status; } return KERN_OK; } static kern_status_t expand_heap(heap_t *heap) { kern_handle_t vmo; kern_status_t status = vm_object_create( "libc-heap-data", 14, HEAP_EXPAND_INCREMENT, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_USER, &vmo); if (status != KERN_OK) { return status; } virt_addr_t base = 0; status = vm_region_map_relative( heap->heap_region, heap->heap_sys_alloc, vmo, 0, HEAP_EXPAND_INCREMENT, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_USER, &base); kern_handle_close(vmo); heap->heap_sys_alloc += HEAP_EXPAND_INCREMENT; return status; } void *heap_expand(heap_t *heap, size_t size) { kern_status_t status = KERN_OK; if (heap->heap_region == KERN_HANDLE_INVALID) { status = init_heap_region(heap); } if (status != KERN_OK) { return NULL; } while (heap->heap_req_alloc + size > heap->heap_sys_alloc) { status = expand_heap(heap); if (status != KERN_OK) { return NULL; } } void *p = (void *)(heap->heap_base + heap->heap_req_alloc); heap->heap_req_alloc += size; return p; }