-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmalloc.h
More file actions
120 lines (95 loc) · 2.75 KB
/
malloc.h
File metadata and controls
120 lines (95 loc) · 2.75 KB
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
#ifndef MALLOC_H
#define MALLOC_H
#include <memoryapi.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <cmath>
#include <stdexcept>
#include "linked_list.h"
#define HEAP_SIZE 8000000
typedef struct {
void* location;
size_t size;
bool freed;
} Block;
static LinkedList<Block> blockList = LinkedList<Block>();
void* myMalloc(const size_t size) {
if (blockList.getHead() == nullptr) {
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
float pageSize = (float)sysInfo.dwPageSize;
int realHeapSize = std::ceil(HEAP_SIZE / pageSize) * pageSize;
Block initialBlock;
initialBlock.size = realHeapSize;
initialBlock.location = VirtualAlloc(NULL, realHeapSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
initialBlock.freed = true;
blockList.shift(initialBlock);
}
Node<Block>* head = blockList.getHead();
while (head->data.size < size || !head->data.freed) {
head = head->next;
}
Block block;
// Reserve a new block
if (head->data.size > size) {
block.size = size;
block.freed = false;
block.location = head->data.location;
head->data.location = static_cast<char*>(head->data.location) + size;
head->data.size -= size;
blockList.shift(block);
} else {
block = head->data;
block.freed = false;
}
return block.location;
}
void myFree(const void* location) {
Node<Block>* ptr = blockList.getHead();
while (ptr != nullptr && ptr->data.location != location)
ptr = ptr->next;
if (ptr == nullptr) {
char buf[64];
snprintf(buf, sizeof(buf), "Unknown memory ptr %p", location);
throw std::runtime_error(buf);
}
ptr->data.freed = true;
Node<Block>* freed = ptr;
// Merge right
ptr = freed->next;
while (ptr != nullptr && ptr->data.freed) {
freed->data.size += ptr->data.size;
freed->next = ptr->next;
Node<Block>* temp = ptr;
ptr = ptr->next;
// Free the node
delete temp;
}
// Merge left
ptr = freed->prev;
while (ptr != nullptr && ptr->data.freed) {
ptr->data.size += freed->data.size;
ptr->next = freed->next;
if (ptr->next != nullptr)
ptr->next->prev = ptr;
delete freed;
freed = ptr;
}
}
void debugBlock(const Block& block) {
printf("Block:\n");
printf("\tLocation: %p\n", block.location);
printf("\tSize: %zu\n", block.size);
printf("\tIs free: %d\n", block.freed);
}
void debugHeap() {
Node<Block>* ptr = blockList.getHead();
while (ptr != nullptr) {
debugBlock(ptr->data);
printf("\n");
ptr = ptr->next;
}
}
#endif