1 | module dlmalloc |
2 | |
3 | $if !freestanding { |
4 | #include <sys/mman.h> |
5 | #include <unistd.h> |
6 | } |
7 | fn C.munmap(ptr voidptr, size usize) int |
8 | fn C.mremap(ptr voidptr, old usize, new usize, flags usize) voidptr |
9 | fn C.mmap(base voidptr, len usize, prot int, flags int, fd int, offset i64) voidptr |
10 | |
11 | pub enum Mm_prot { |
12 | prot_read = 0x1 |
13 | prot_write = 0x2 |
14 | prot_exec = 0x4 |
15 | prot_none = 0x0 |
16 | prot_growsdown = 0x01000000 |
17 | prot_growsup = 0x02000000 |
18 | } |
19 | |
20 | pub enum Map_flags { |
21 | map_shared = 0x01 |
22 | map_private = 0x02 |
23 | map_shared_validate = 0x03 |
24 | map_type = 0x0f |
25 | map_fixed = 0x10 |
26 | map_file = 0x00 |
27 | map_anonymous = 0x20 |
28 | map_huge_shift = 26 |
29 | map_huge_mask = 0x3f |
30 | } |
31 | |
32 | enum MemProt { |
33 | prot_read = 0x1 |
34 | prot_write = 0x2 |
35 | prot_exec = 0x4 |
36 | prot_none = 0x0 |
37 | prot_growsdown = 0x01000000 |
38 | prot_growsup = 0x02000000 |
39 | } |
40 | |
41 | enum MapFlags { |
42 | map_shared = 0x01 |
43 | map_private = 0x02 |
44 | map_shared_validate = 0x03 |
45 | map_type = 0x0f |
46 | map_fixed = 0x10 |
47 | map_file = 0x00 |
48 | map_anonymous = 0x20 |
49 | map_huge_shift = 26 |
50 | map_huge_mask = 0x3f |
51 | } |
52 | |
53 | fn system_alloc(_ voidptr, size usize) (voidptr, usize, u32) { |
54 | $if !freestanding { |
55 | unsafe { |
56 | mem_prot := MemProt(int(MemProt.prot_read) | int(MemProt.prot_write)) |
57 | map_flags := MapFlags(int(MapFlags.map_private) | int(MapFlags.map_anonymous)) |
58 | addr := C.mmap(nil, size, int(mem_prot), int(map_flags), -1, 0) |
59 | |
60 | if addr == voidptr(-1) { |
61 | return nil, 0, 0 |
62 | } else { |
63 | return addr, size, 0 |
64 | } |
65 | } |
66 | } $else { |
67 | return unsafe { nil }, 0, 0 |
68 | } |
69 | return unsafe { nil }, 0, 0 |
70 | } |
71 | |
72 | fn system_remap(_ voidptr, ptr voidptr, oldsize usize, newsize usize, can_move bool) voidptr { |
73 | return unsafe { nil } |
74 | } |
75 | |
76 | fn system_free_part(_ voidptr, ptr voidptr, oldsize usize, newsize usize) bool { |
77 | $if linux && !freestanding { |
78 | unsafe { |
79 | rc := C.mremap(ptr, oldsize, newsize, 0) |
80 | if rc != voidptr(-1) { |
81 | return true |
82 | } |
83 | return C.munmap(voidptr(usize(ptr) + newsize), oldsize - newsize) == 0 |
84 | } |
85 | } $else $if macos && !freestanding { |
86 | unsafe { |
87 | return C.munmap(voidptr(usize(ptr) + newsize), oldsize - newsize) == 0 |
88 | } |
89 | } |
90 | return false |
91 | } |
92 | |
93 | fn system_free(_ voidptr, ptr voidptr, size usize) bool { |
94 | $if !freestanding { |
95 | unsafe { |
96 | return C.munmap(ptr, size) == 0 |
97 | } |
98 | } $else { |
99 | return false |
100 | } |
101 | } |
102 | |
103 | fn system_can_release_part(_ voidptr, _ u32) bool { |
104 | return true |
105 | } |
106 | |
107 | fn system_allocates_zeros(_ voidptr) bool { |
108 | return true |
109 | } |
110 | |
111 | fn system_page_size(_ voidptr) usize { |
112 | return 4096 |
113 | } |
114 | |
115 | pub fn get_system_allocator() Allocator { |
116 | return Allocator{ |
117 | alloc: system_alloc |
118 | remap: system_remap |
119 | free_part: system_free_part |
120 | free_: system_free |
121 | can_release_part: system_can_release_part |
122 | allocates_zeros: system_allocates_zeros |
123 | page_size: system_page_size |
124 | data: unsafe { nil } |
125 | } |
126 | } |