pawengine/allocator.c
2025-02-09 18:48:25 +01:00

88 lines
2.1 KiB
C

#include "log.h"
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#define MAX_ALLOCS 256
struct Alloc {
void *start;
uint size;
struct Alloc *next;
};
struct Mem {
void *mem;
size_t mem_size;
uint count;
struct Alloc *alloc;
struct Alloc allocs[MAX_ALLOCS];
};
struct Mem *make_mem(size_t size) {
struct Mem *mem = malloc(sizeof(struct Mem));
mem->mem_size = size;
mem->mem = malloc(mem->mem_size);
memset(mem->mem, 0, mem->mem_size);
mem->count = 0;
memset(&mem->allocs, 0, sizeof(struct Alloc) * MAX_ALLOCS);
mem->allocs[0] = (struct Alloc){mem->mem + mem->mem_size, 0, NULL};
mem->allocs[1] = (struct Alloc){mem->mem, 0, &mem->allocs[0]};
mem->alloc = &mem->allocs[1];
return mem;
}
void uninit_mem(struct Mem *mem) {
free(mem->mem);
free(mem);
}
static struct Alloc *get_next_alloc(struct Mem *mem) {
uint index = mem->count;
mem->count++;
while (*(char *)&mem->allocs[mem->count] != 0) {
mem->count++;
if (mem->count >= MAX_ALLOCS) {
crash("out of allocs!");
}
}
return &mem->allocs[index];
}
void *mem_malloc(struct Mem *mem, size_t size) {
struct Alloc *prev = mem->alloc;
while (prev->next != NULL) {
struct Alloc *next = prev->next;
if (next->start - (prev->start + prev->size) > size) {
struct Alloc *new = get_next_alloc(mem);
*new = (struct Alloc){
prev->start + prev->size,
size,
next,
};
prev->next = new;
meow("MALLOC %p of size %zu, prev is at %p with size %u", new->start,
size, prev->start, prev->size);
/* print_backtrace(); */
return new->start;
} else {
prev = next;
}
}
crash("no big enaugh free space found!");
return NULL;
}
void mem_free(struct Mem *mem, void *p) {
struct Alloc *current = mem->alloc;
struct Alloc *prev = mem->alloc;
while (p < current->start) {
prev = current;
current = current->next;
}
prev->next = current->next;
int index = current - mem->allocs;
if (index < mem->count) {
mem->count = index;
}
memset(&mem->allocs[index], 0, sizeof(struct Alloc));
}