Source file
src/runtime/mem_linux.go
Documentation: runtime
1
2
3
4
5 package runtime
6
7 import (
8 "runtime/internal/atomic"
9 "unsafe"
10 )
11
12 const (
13 _EACCES = 13
14 _EINVAL = 22
15 )
16
17
18
19
20
21 func sysAllocOS(n uintptr) unsafe.Pointer {
22 p, err := mmap(nil, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
23 if err != 0 {
24 if err == _EACCES {
25 print("runtime: mmap: access denied\n")
26 exit(2)
27 }
28 if err == _EAGAIN {
29 print("runtime: mmap: too much locked memory (check 'ulimit -l').\n")
30 exit(2)
31 }
32 return nil
33 }
34 return p
35 }
36
37 var adviseUnused = uint32(_MADV_FREE)
38
39 const madviseUnsupported = 0
40
41 func sysUnusedOS(v unsafe.Pointer, n uintptr) {
42 if uintptr(v)&(physPageSize-1) != 0 || n&(physPageSize-1) != 0 {
43
44
45
46 throw("unaligned sysUnused")
47 }
48
49 advise := atomic.Load(&adviseUnused)
50 if debug.madvdontneed != 0 && advise != madviseUnsupported {
51 advise = _MADV_DONTNEED
52 }
53 switch advise {
54 case _MADV_FREE:
55 if madvise(v, n, _MADV_FREE) == 0 {
56 break
57 }
58 atomic.Store(&adviseUnused, _MADV_DONTNEED)
59 fallthrough
60 case _MADV_DONTNEED:
61
62
63 if madvise(v, n, _MADV_DONTNEED) == 0 {
64 break
65 }
66 atomic.Store(&adviseUnused, madviseUnsupported)
67 fallthrough
68 case madviseUnsupported:
69
70
71
72
73 mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
74 }
75
76 if debug.harddecommit > 0 {
77 p, err := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
78 if p != v || err != 0 {
79 throw("runtime: cannot disable permissions in address space")
80 }
81 }
82 }
83
84 func sysUsedOS(v unsafe.Pointer, n uintptr) {
85 if debug.harddecommit > 0 {
86 p, err := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
87 if err == _ENOMEM {
88 throw("runtime: out of memory")
89 }
90 if p != v || err != 0 {
91 throw("runtime: cannot remap pages in address space")
92 }
93 return
94 }
95 }
96
97 func sysHugePageOS(v unsafe.Pointer, n uintptr) {
98 if physHugePageSize != 0 {
99
100 beg := alignUp(uintptr(v), physHugePageSize)
101
102 end := alignDown(uintptr(v)+n, physHugePageSize)
103
104 if beg < end {
105 madvise(unsafe.Pointer(beg), end-beg, _MADV_HUGEPAGE)
106 }
107 }
108 }
109
110 func sysNoHugePageOS(v unsafe.Pointer, n uintptr) {
111 if uintptr(v)&(physPageSize-1) != 0 {
112
113
114 throw("unaligned sysNoHugePageOS")
115 }
116 madvise(v, n, _MADV_NOHUGEPAGE)
117 }
118
119 func sysHugePageCollapseOS(v unsafe.Pointer, n uintptr) {
120 if uintptr(v)&(physPageSize-1) != 0 {
121
122
123 throw("unaligned sysHugePageCollapseOS")
124 }
125 if physHugePageSize == 0 {
126 return
127 }
128
129
130
131
132
133
134
135
136
137
138
139
140
141 madvise(v, n, _MADV_COLLAPSE)
142 }
143
144
145
146
147
148 func sysFreeOS(v unsafe.Pointer, n uintptr) {
149 munmap(v, n)
150 }
151
152 func sysFaultOS(v unsafe.Pointer, n uintptr) {
153 mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE|_MAP_FIXED, -1, 0)
154 }
155
156 func sysReserveOS(v unsafe.Pointer, n uintptr) unsafe.Pointer {
157 p, err := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
158 if err != 0 {
159 return nil
160 }
161 return p
162 }
163
164 func sysMapOS(v unsafe.Pointer, n uintptr) {
165 p, err := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
166 if err == _ENOMEM {
167 throw("runtime: out of memory")
168 }
169 if p != v || err != 0 {
170 print("runtime: mmap(", v, ", ", n, ") returned ", p, ", ", err, "\n")
171 throw("runtime: cannot map pages in arena address space")
172 }
173
174
175
176
177
178 if debug.disablethp != 0 {
179 sysNoHugePageOS(v, n)
180 }
181 }
182
View as plain text