|
4 | 4 |
|
5 | 5 | #define CHUNK_SIZE 16384 // 16KB
|
6 | 6 |
|
7 |
| -let free_list *u8; |
| 7 | +#define HEAP_SIZE 2147483647 |
8 | 8 |
|
9 |
| -func memset(ptr *u8, val u8, n i32) u0 { |
10 |
| - for let i i32 = 0; i < n; i++ { |
11 |
| - ptr[i] = val; |
12 |
| - } |
13 |
| -} |
14 |
| - |
15 |
| -func sbrk(increment i32) *u8 { |
16 |
| - let old_break *u8 = brk(0); |
17 |
| - if old_break < 1 { |
18 |
| - return nil; |
19 |
| - } |
20 |
| - |
21 |
| - let new_break *u8 = old_break + increment; |
| 9 | +let heap_head *u8; |
| 10 | +let heap_current *u8; |
| 11 | +let heap_tail *u8; |
22 | 12 |
|
23 |
| - let result *u8 = brk(new_break); |
24 |
| - if result < 1 { |
25 |
| - return nil; |
26 |
| - } |
27 |
| - |
28 |
| - return old_break; |
29 |
| -} |
30 |
| - |
31 |
| -func find_free_block(size i32) *BlockHeader { |
32 |
| - let current *BlockHeader = free_list; |
33 |
| - while current != nil { |
34 |
| - if current.is_free && current.size >= size + typesize(BlockHeader) { |
35 |
| - return current; |
36 |
| - } |
37 |
| - current = current.next; |
| 13 | +func heap_init() u0 { |
| 14 | + heap_head = brk(0); |
| 15 | + heap_tail = brk(heap_head + HEAP_SIZE * 2); |
| 16 | + if (heap_head % 8) == 0 { |
| 17 | + heap_current = heap_head; |
| 18 | + } else { |
| 19 | + heap_current = heap_head + (8 - (heap_head % 8)); |
38 | 20 | }
|
39 |
| - return nil; |
40 | 21 | }
|
41 | 22 |
|
42 |
| -func request_space(size i32) *BlockHeader { |
43 |
| - let request_size i32 = size + typesize(BlockHeader); |
44 |
| - |
45 |
| - let new_heap_head *BlockHeader = sbrk(request_size); |
46 |
| - if new_heap_head < 1 { |
47 |
| - return nil; |
| 23 | +func memset(ptr *u8, val u8, n i32) u0 { |
| 24 | + for let i i32 = 0; i < n; i++ { |
| 25 | + ptr[i] = val; |
48 | 26 | }
|
49 |
| - |
50 |
| - memset(new_heap_head, 0, request_size); |
51 |
| - |
52 |
| - new_heap_head.size = request_size; |
53 |
| - new_heap_head.is_free = false; |
54 |
| - new_heap_head.next = nil; |
55 |
| - |
56 |
| - return new_heap_head; |
57 | 27 | }
|
58 | 28 |
|
59 | 29 | func alloc(size i32) *u8 {
|
60 |
| - if size <= 0 { |
61 |
| - return nil; |
62 |
| - } |
63 |
| - |
64 |
| - let aligned_size i32 = size; |
65 |
| - let block *BlockHeader = find_free_block(aligned_size); |
66 |
| - if block == nil { |
67 |
| - block = request_space(aligned_size); |
68 |
| - if block == nil { |
69 |
| - return nil; |
70 |
| - } |
71 |
| - } else { |
72 |
| - if block == free_list { |
73 |
| - free_list = block.next; |
74 |
| - } else { |
75 |
| - let prev *BlockHeader = free_list; |
76 |
| - while prev.next != block { |
77 |
| - prev = prev.next; |
78 |
| - } |
79 |
| - prev.next = block.next; |
80 |
| - } |
81 |
| - block.is_free = false; |
82 |
| - block.next = nil; |
| 30 | + if heap_current == nil { |
| 31 | + heap_init(); |
83 | 32 | }
|
84 | 33 |
|
85 |
| - return block + typesize(BlockHeader); |
86 |
| -} |
87 |
| - |
88 |
| -func free(ptr *u8) u0 { |
89 |
| - if ptr == nil { |
90 |
| - return; |
| 34 | + if heap_current + size > heap_tail { |
| 35 | + eprintf("heap overflow\n"); |
| 36 | + exit(1); |
91 | 37 | }
|
92 |
| - let block *BlockHeader = ptr - typesize(BlockHeader); |
93 |
| - block.is_free = true; |
94 | 38 |
|
95 |
| - block.next = free_list; |
96 |
| - free_list = block; |
| 39 | + let result *u8 = heap_current; |
| 40 | + heap_current = heap_current + size; |
| 41 | + memset(result, 0, size); |
| 42 | + return result; |
97 | 43 | }
|
98 | 44 |
|
99 | 45 | func strcmp(a *u8, b *u8) bool {
|
@@ -186,8 +132,6 @@ func memmove(dest *u8, src *u8, n u32) u0 {
|
186 | 132 | *(p_dest + i) = *(tmp + i);
|
187 | 133 | }
|
188 | 134 | }
|
189 |
| - |
190 |
| - free(tmp); |
191 | 135 | }
|
192 | 136 |
|
193 | 137 | func byte_to_lower(c u8) u8 {
|
|
0 commit comments