summaryrefslogtreecommitdiff
path: root/src/init/malloc.c
blob: eb63d8285b55b1ea65109c69cfa4a735e7e0f1e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <init/malloc.h>
#include <shared/flags.h>
#include <shared/syscalls.h>
#include <stdbool.h>

#include <init/stdlib.h>

#define MBLOCK_MAGIC 0x1337BABE

struct mblock {
	uint32_t magic;
	size_t length; // including this struct
	bool used;
	struct mblock *next;
};

static struct mblock *first = NULL, *last = NULL;
static struct mblock *expand(size_t size);

void *malloc(size_t size) {
	struct mblock *iter = first;
	size += sizeof(struct mblock);
	while (iter) {
		if (!iter->used && iter->length >= size)
			break;
		iter = iter->next;
	}

	if (!iter) iter = expand(size);
	if (!iter) return NULL;

	iter->used = true;
	// TODO truncate and split

	return &iter[1];
}

void free(void *ptr) {
	struct mblock *block = ptr - sizeof(struct mblock);
	if (block->magic != MBLOCK_MAGIC) {
		// TODO debug log switch
		printf("didn't find MBLOCK_MAGIC @ 0x%x\n", block);
		return;
	}

	block->used = false;
}

static struct mblock *expand(size_t size) {
	struct mblock *block = _syscall_memflag(0, size, MEMFLAG_PRESENT | MEMFLAG_FINDFREE);
	if (!block) return NULL;

	block->magic = MBLOCK_MAGIC;
	block->length = size;
	block->used = false;
	block->next = NULL;

	if (!first) first = block;
	if (last) last->next = block;
	last = block;

	// TODO collapse

	return block;
}