-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathalloc.c
141 lines (121 loc) · 3.3 KB
/
alloc.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include "alloc.h"
#include "screentext.h"
#ifdef TESTING
#include <stdlib.h>
#include <stdio.h>
#endif
#define MEM_LO 0x8000
#define MEM_SIZE 0x80000
blockhdr *link = NULL;
int mm_init(void) {
void *mem_low = (void *)MEM_LO;
blockhdr *lowloc = (blockhdr *)mem_low;
lowloc->nxpr = MEM_SIZE - sizeof(struct header);
lowloc->free = 1;
lowloc->frst = 1;
lowloc->last = 1;
link = lowloc;
blockhdr *highloc = (blockhdr *)(mem_low + MEM_SIZE - sizeof(struct header));
highloc->nxpr = MEM_SIZE - sizeof(struct header);
highloc->free = 1;
highloc->frst = 1;
highloc->last = 1;
return 0;
}
int split_block(blockhdr *block, size_t size) {
if (block->nxpr == size + sizeof(struct header)) {
return 0;
}
blockhdr *newtail = ((void *)block) + (size + sizeof(struct header));
blockhdr *nexthead = ((void *)block) + (size + 2*sizeof(struct header));
blockhdr *last = ((void *)block) + (block->nxpr);
size_t sblock_size = block->nxpr - size - 2*sizeof(struct header);
if (sblock_size > MEM_SIZE) {
return 1;
}
newtail->free = 1;
nexthead->free = 1;
newtail->nxpr = block->nxpr = size + sizeof(struct header);
last->nxpr = nexthead->nxpr = sblock_size;
nexthead->last = block->last;
block->last = 0;
nexthead->frst = 0;
return 0;
}
void* mm_alloc(size_t size) {
if (size <= 0) {
console_print("size too small");
return NULL;
}
if (size%8) {
size = ((size>>3)+1)<<3;
}
blockhdr *tmp = link;
while(!tmp->free || tmp->nxpr <= size + sizeof(struct header)) {
tmp = (blockhdr *)(((void *)tmp) + tmp->nxpr + sizeof(struct header));
}
if (split_block(tmp, size)) {
return NULL;
}
tmp->free = 0;
return ((void *)tmp) + sizeof(struct header);
}
void mergeblocks(blockhdr *data, blockhdr *next) {
data->last = next->last;
data->nxpr = (data->nxpr + next->nxpr + sizeof(struct header));
blockhdr *last = ((void *)next) + next->nxpr;
last->nxpr = data->nxpr;
last->frst = data->frst;
}
void mm_free(void* ptr) {
blockhdr *data = ptr-sizeof(struct header);
data->free = 1;
if (!data->last) {
blockhdr *next = ((void *)data) + data->nxpr + sizeof(struct header);
if (next->free) {
mergeblocks(data, next);
}
}
if (!data->frst) {
blockhdr *prev = ((void *)data) - sizeof(struct header);
if (prev->free) {
prev = ((void *)prev) - prev->nxpr;
mergeblocks(prev, data);
}
}
}
void blockcheck() {
blockhdr *tmp = link;
int x = 100;
while(x-->0) {
if (!tmp->last) {
tmp = ((void *)tmp) + tmp->nxpr + sizeof(struct header);
} else {
break;
}
}
}
void* mm_zalloc(size_t size) {
void *mem = mm_alloc(size);
if (mem == 0) {
return mem;
}
blockhdr *t = ((void *)mem) - sizeof(struct header);
size = t->nxpr;
char *c = (char *)mem;
int i = 0;
for(;i<size;i++) {
c[i] = 0;
}
return mem;
}
size_t mm_copy(void *new, void *old, size_t bytes) {
char *n = (char *)new;
char *o = (char *)old;
int i = 0;
for(;i<bytes;i++) {
*(n++) = *(o++);
}
return 0;
}
void* mm_realloc(void* ptr, size_t size);