71 lines
1.5 KiB
C
71 lines
1.5 KiB
C
#include "alloc.h"
|
|
#include "assert.h"
|
|
#include "kprintf.h"
|
|
#include "memory.h"
|
|
#include "string.h"
|
|
|
|
Zone *kzones[3];
|
|
|
|
static void add_zone(Zone *zone, block_type_t type)
|
|
{
|
|
// We put the zone at the beginning of the list
|
|
if (kzones[type]) {
|
|
assert(kzones[type] != zone);
|
|
zone->next = kzones[type];
|
|
kzones[type]->prev = zone;
|
|
}
|
|
kzones[type] = zone;
|
|
}
|
|
|
|
static void new_block(Zone *zone, uint32_t zone_size)
|
|
{
|
|
Block *new_block = (Block *)align_mem((uint32_t)zone + sizeof(Zone));
|
|
|
|
// Metadata
|
|
new_block->in_use = false;
|
|
new_block->size = zone_size - sizeof(Zone) - sizeof(Block);
|
|
new_block->sub_size = new_block->size;
|
|
new_block->ptr = (Block *)((uint32_t)new_block + sizeof(Block));
|
|
new_block->zone = zone;
|
|
|
|
// Init future linked lists
|
|
new_block->prev = NULL;
|
|
new_block->prev_free = NULL;
|
|
new_block->prev_used = NULL;
|
|
new_block->next = NULL;
|
|
new_block->next_free = NULL;
|
|
new_block->next_used = NULL;
|
|
|
|
if (zone->free) {
|
|
zone->free->prev = new_block;
|
|
zone->free->prev_free = new_block;
|
|
new_block->next = zone->free;
|
|
new_block->next_free = zone->free;
|
|
}
|
|
zone->free = new_block;
|
|
assert(zone->free == new_block);
|
|
}
|
|
|
|
int new_kzone(block_type_t type, uint32_t size)
|
|
{
|
|
// assert(current_task->pid);
|
|
void *heap = kalloc_pages(size);
|
|
if (heap == NULL) {
|
|
kprintf(KERN_ERR "error: alloc_frame failed\n");
|
|
return (-1);
|
|
}
|
|
memset(heap, 0, size);
|
|
|
|
Zone *zone = (Zone *)heap;
|
|
zone->type = type;
|
|
zone->size = size;
|
|
zone->used = NULL;
|
|
zone->next = NULL;
|
|
zone->prev = NULL;
|
|
|
|
new_block(zone, size);
|
|
add_zone(heap, type);
|
|
|
|
return (0);
|
|
}
|