lib: c: combine libc and ulibc
libc is now made up of several independent components, each of which is individually compiled into a static library. they are then all combined into a single shared library.
This commit is contained in:
112
lib/libc/malloc/heap.c
Normal file
112
lib/libc/malloc/heap.c
Normal file
@@ -0,0 +1,112 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user