feat: introduced tasking, added paging (no vm), moved malloc, added
syscalls, other stuff
This commit is contained in:
90
kernel/mem/malloc.c
Normal file
90
kernel/mem/malloc.c
Normal file
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// Created by rick on 23-02-21.
|
||||
//
|
||||
|
||||
#include <libc/kprintf.h>
|
||||
#include <tasks/task.h>
|
||||
#include "malloc.h"
|
||||
#include "pmm.h"
|
||||
|
||||
#define MALLOC_TYPE_FREE 0
|
||||
#define MALLOC_TYPE_USED 1
|
||||
|
||||
int malloc_entries = 0;
|
||||
int malloc_used = 0;
|
||||
|
||||
typedef struct malloc_map {
|
||||
struct malloc_map *next;
|
||||
struct malloc_map *prev;
|
||||
uint32_t size;
|
||||
int type;
|
||||
} malloc_map;
|
||||
|
||||
malloc_map *first_malloc_entry;
|
||||
|
||||
void malloc_init() {
|
||||
first_malloc_entry = pmm_get_pages(16);
|
||||
first_malloc_entry->next = first_malloc_entry;
|
||||
first_malloc_entry->prev = first_malloc_entry;
|
||||
first_malloc_entry->size = PAGE_SIZE * 16;
|
||||
first_malloc_entry->type = MALLOC_TYPE_FREE;
|
||||
malloc_entries++;
|
||||
}
|
||||
|
||||
void split_malloc_map(malloc_map *entry, unsigned int size) {
|
||||
malloc_entries++;
|
||||
malloc_map *new_entry = entry + sizeof(malloc_map) + size;
|
||||
new_entry->size = entry->size - size - sizeof(malloc_map);
|
||||
new_entry->next = entry->next;
|
||||
new_entry->prev = entry;
|
||||
new_entry->type = MALLOC_TYPE_FREE;
|
||||
entry->next->prev = new_entry;
|
||||
entry->next = new_entry;
|
||||
entry->size = size;
|
||||
}
|
||||
|
||||
void *malloc(size_t size) {
|
||||
// todo replace this horrible mess!
|
||||
// this lacks any page alignment and what so ever
|
||||
void* result = NULL;
|
||||
task_lock_acquire();
|
||||
malloc_map *current_map = first_malloc_entry;
|
||||
// iterate through maps
|
||||
do {
|
||||
if (current_map->type == MALLOC_TYPE_USED) {
|
||||
goto malloc_find_next;
|
||||
}
|
||||
if ((unsigned int) current_map->size < size) {
|
||||
goto malloc_find_next;
|
||||
}
|
||||
if ((unsigned int) current_map->size > (size + sizeof(malloc_map))) {
|
||||
// big enough to split
|
||||
split_malloc_map(current_map, size);
|
||||
}
|
||||
malloc_used++;
|
||||
current_map->type = MALLOC_TYPE_USED;
|
||||
result = ((void *) current_map) + sizeof(malloc_map);
|
||||
break;
|
||||
|
||||
malloc_find_next:
|
||||
current_map = current_map->next;
|
||||
} while (current_map != first_malloc_entry);
|
||||
task_lock_free();
|
||||
return result;
|
||||
}
|
||||
|
||||
void free(void *mem) {
|
||||
if (mem == NULL) {
|
||||
return;
|
||||
}
|
||||
malloc_used--;
|
||||
malloc_map *map = (mem - sizeof(malloc_map));
|
||||
map->type = MALLOC_TYPE_FREE;
|
||||
};
|
||||
|
||||
|
||||
void print_malloc_info() {
|
||||
printf("Malloc avail entries: %d\n"
|
||||
"Malloc used entries: %d\n", malloc_entries, malloc_used);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user