-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathheap.c
executable file
·78 lines (68 loc) · 1.94 KB
/
heap.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
#include <stdbool.h>
#include "terminal.h"
#include "heap.h"
struct heapblock
{
struct heapblock* next;
bool isFree;
int allocationSize;
unsigned char userdata[0];
}; typedef struct heapblock heapblock;
heapblock* heapBase;
void initHeap()
{
heapBase = (heapblock*)0x00200000;
heapBase->next = 0;
heapBase->isFree = true;
heapBase->allocationSize = 0x10000 - sizeof(heapblock);
}
void* allocHeap(int requestedSize)
{
heapblock* candidate = heapBase;
do
{
if (!candidate->isFree || candidate->allocationSize < requestedSize)
{
candidate = candidate->next;
continue;
}
// OK, this block is free and can accomodate the request. We need to size if appropriately, mark it in use, and -
// if the requested block is smaller than the block we're going to use - initialize the block after it to be a free block.
if (candidate->allocationSize == requestedSize)
{
candidate->isFree = false;
return candidate->userdata;
}
heapblock* newBlock = (heapblock*)&candidate->userdata[requestedSize];
newBlock->isFree = true;
newBlock->allocationSize = candidate->allocationSize - (requestedSize + sizeof(heapblock));
newBlock->next = candidate->next;
candidate->next = newBlock;
candidate->allocationSize = requestedSize;
candidate->isFree = false;
return candidate->userdata;
} while (candidate != 0);
return NULL;
}
void freeHeap(void* userdata)
{
heapblock* toFree = (heapblock*)(((char*)userdata) - sizeof(heapblock));
toFree->isFree = true;
}
void dumpHeap(void)
{
heapblock* candidate = heapBase;
do
{
terminal_writestring("Block at ");
terminal_writeptr(candidate);
if (candidate->isFree)
terminal_writestring(": free");
else
terminal_writestring(": busy");
terminal_writestring(" size ");
terminal_writeuint32(candidate->allocationSize);
terminal_writestring("\n");
candidate = candidate->next;
} while (candidate != 0);
}