forked from mwkmwkmwk/zso-os
-
Notifications
You must be signed in to change notification settings - Fork 0
/
malloc.c
91 lines (76 loc) · 2.33 KB
/
malloc.c
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <stddef.h>
#include "malloc.h"
extern char end;
static void *malloc_pool = &end;
static void *free_list_head = NULL;
static void *find_free(size_t sz) {
void *this = free_list_head,
*prev = NULL;
while (this != NULL) {
//TODO maybe change to >= ?
if (MALLOC_GET_SIZE(this) == sz) {
if (prev == NULL) {
free_list_head = MALLOC_GET_NEXT_PTR_ADDR(this);
} else {
MALLOC_GET_NEXT_PTR_ADDR(prev) = MALLOC_GET_NEXT_PTR_ADDR(this);
}
MALLOC_GET_NEXT_PTR_ADDR(this) = NULL;
return this;
}
prev = this;
this = MALLOC_GET_NEXT_PTR_ADDR(this);
}
return NULL;
}
static void *_malloc(size_t sz, int use_freed) {
void *ptr = NULL;
sz = (sz + MALLOC_ALIGN_BITS) & ~MALLOC_ALIGN_BITS;
if (use_freed) {
ptr = find_free(sz);
}
if (ptr == NULL) {
// if end is aligned then this can be removed
malloc_pool = (void *)(((uint64_t)malloc_pool + MALLOC_ALIGN_BITS) & ~MALLOC_ALIGN_BITS);
ptr = ADD_OFF(malloc_pool, MALLOC_HEADER_SIZE, void);
malloc_pool += MALLOC_HEADER_SIZE + sz;
MALLOC_GET_NEXT_PTR_ADDR(ptr) = NULL;
MALLOC_GET_SIZE(ptr) = sz;
}
return ptr;
}
void *malloc(size_t sz) {
return _malloc(sz, 1);
}
void free(void *ptr) {
void *next = free_list_head;
if (ptr == NULL) {
return;
}
if (ADD_OFF(ptr, MALLOC_GET_SIZE(ptr), void *) == malloc_pool) {
malloc_pool -= MALLOC_GET_SIZE(ptr) + MALLOC_HEADER_SIZE;
return;
}
if (free_list_head == NULL) {
free_list_head = ptr;
return;
}
while (MALLOC_GET_NEXT_PTR_ADDR(next) != NULL) {
next = MALLOC_GET_NEXT_PTR_ADDR(next);
}
MALLOC_GET_NEXT_PTR_ADDR(next) = ptr;
}
// uhm, I should be killed for writting this
void *alloc_pages(size_t count) {
void *ptr = NULL,
*ret = NULL;
uint64_t size_to_page_end = (((uint64_t)malloc_pool + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) - (uint64_t)malloc_pool;
if (size_to_page_end != MALLOC_HEADER_SIZE) {
if (size_to_page_end == 0) {
size_to_page_end = PAGE_SIZE;
}
ptr = _malloc(size_to_page_end - 2 * MALLOC_HEADER_SIZE, 0);
}
ret = malloc(PAGE_SIZE * count);
free(ptr);
return ret;
}