89 lines
2.1 KiB
C
89 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));
|
||
|
}
|