Files

113 lines
2.1 KiB
C
Raw Permalink Normal View History

#include "liballoc.h"
#include <heap/heap.h>
#include <mango/handle.h>
#include <mango/log.h>
#include <mango/status.h>
#include <mango/task.h>
#include <mango/vm.h>
#include <stdio.h>
#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;
}