-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathmem.c
99 lines (84 loc) · 2.51 KB
/
mem.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
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <sys/mman.h>
uint64_t* HEAP_START;
#define HEAP_SIZE 1024
#define VAL_SIZE 8
#define HEAP_END (HEAP_START + (HEAP_SIZE / VAL_SIZE))
uint64_t size(uint64_t* heap_ptr) {
return *heap_ptr & 0xFFFFFFFFFFFFFFFE;
}
uint64_t val_size(uint64_t* heap_ptr) {
return (*heap_ptr & 0xFFFFFFFFFFFFFFFE) / VAL_SIZE;
}
uint8_t isfree(uint64_t* heap_ptr) {
return (*heap_ptr & 1) == 0;
}
void init_heap() {
HEAP_START = mmap(NULL, HEAP_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
// Set the first value in the heap to be the size minus one value
*HEAP_START = HEAP_SIZE - VAL_SIZE;
*(HEAP_START + (HEAP_SIZE / VAL_SIZE)) = HEAP_SIZE - VAL_SIZE;
}
void* do_alloc(uint64_t* heap_ptr, size_t size_req) {
printf("comparing: %llu %lu\n", size(heap_ptr), size_req);
if(size(heap_ptr) >= (size_req + 16)) {
size_t size_rounded = size_req % 16 == 0 ? size_req : ((size_req + 16) / 16) * 16;
uint64_t* split_after = heap_ptr + 1 + (size_rounded / VAL_SIZE);
printf("Writing to %p that %llu bytes free\n", split_after, size(heap_ptr) - size_rounded - VAL_SIZE);
*split_after = size(heap_ptr) - size_rounded - VAL_SIZE;
*heap_ptr = size_rounded;
}
*heap_ptr |= 1;
printf("%llu\n", *heap_ptr);
return heap_ptr + 1;
}
void* mymalloc(size_t size_req) {
uint64_t* heap_ptr = HEAP_START;
while(heap_ptr < HEAP_END) {
if(isfree(heap_ptr) && ((size(heap_ptr) >= size_req))) {
return do_alloc(heap_ptr, size_req);
}
heap_ptr += val_size(heap_ptr) + 1;
}
return NULL;
}
void myfree(void* v) {
uint64_t* heap_ptr = ((uint64_t*)v) - 1;
if(isfree(heap_ptr)) { return; }
*heap_ptr -= 1;
}
void show_heap() {
printf("HEAP_START: %p = %llu, HEAP_END: %p\n", HEAP_START, *HEAP_START, HEAP_END);
uint64_t* heap_ptr = HEAP_START;
printf("ADDRESS\t\tFREE?\tSIZE\n\n");
while(heap_ptr < HEAP_END) {
printf("%p\t", heap_ptr);
printf("%s\t", *heap_ptr % 2 == 0 ? "FREE" : "ALLOC");
printf("%llu\t", (*heap_ptr) / 2 * 2);
heap_ptr += val_size(heap_ptr) + 1;
printf("\n");
}
if(0) {
printf("\n(RAW)\n");
printf("ADDRESS\t\tVALUE");
heap_ptr = HEAP_START;
while(heap_ptr < HEAP_END) {
printf("%p\t\t%llu\t\t%llx\n", heap_ptr, *heap_ptr, *heap_ptr);
heap_ptr += 1;
}
}
}
int main() {
init_heap();
show_heap();
int* hi = mymalloc(10);
show_heap();
int* hi2 = mymalloc(100);
show_heap();
myfree(hi);
show_heap();
int* hi3 = mymalloc(10);
show_heap();
}