91 lines
2.3 KiB
C
91 lines
2.3 KiB
C
//
|
|
// 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);
|
|
}
|
|
|