Source file
src/runtime/mem_linux.go
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 func sysAlloc(n uintptr, sysStat *sysMemStat) unsafe.Pointer {
21 p, err := mmap(nil, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
22 if err != 0 {
23 if err == _EACCES {
24 print("runtime: mmap: access denied\n")
25 exit(2)
26 }
27 if err == _EAGAIN {
28 print("runtime: mmap: too much locked memory (check 'ulimit -l').\n")
29 exit(2)
30 }
31 return nil
32 }
33 sysStat.add(int64(n))
34 return p
35 }
36
37 var adviseUnused = uint32(_MADV_FREE)
38
39 func sysUnused(v unsafe.Pointer, n uintptr) {
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 if physHugePageSize != 0 {
66
67
68
69
70 var head, tail uintptr
71 if uintptr(v)&(physHugePageSize-1) != 0 {
72
73 head = alignDown(uintptr(v), physHugePageSize)
74 }
75 if (uintptr(v)+n)&(physHugePageSize-1) != 0 {
76
77 tail = alignDown(uintptr(v)+n-1, physHugePageSize)
78 }
79
80
81
82
83 if head != 0 && head+physHugePageSize == tail {
84
85
86 madvise(unsafe.Pointer(head), 2*physHugePageSize, _MADV_NOHUGEPAGE)
87 } else {
88
89 if head != 0 {
90 madvise(unsafe.Pointer(head), physHugePageSize, _MADV_NOHUGEPAGE)
91 }
92 if tail != 0 && tail != head {
93 madvise(unsafe.Pointer(tail), physHugePageSize, _MADV_NOHUGEPAGE)
94 }
95 }
96 }
97
98 if uintptr(v)&(physPageSize-1) != 0 || n&(physPageSize-1) != 0 {
99
100
101
102 throw("unaligned sysUnused")
103 }
104
105 var advise uint32
106 if debug.madvdontneed != 0 {
107 advise = _MADV_DONTNEED
108 } else {
109 advise = atomic.Load(&adviseUnused)
110 }
111 if errno := madvise(v, n, int32(advise)); advise == _MADV_FREE && errno != 0 {
112
113
114 atomic.Store(&adviseUnused, _MADV_DONTNEED)
115 madvise(v, n, _MADV_DONTNEED)
116 }
117
118 if debug.harddecommit > 0 {
119 p, err := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
120 if p != v || err != 0 {
121 throw("runtime: cannot disable permissions in address space")
122 }
123 }
124 }
125
126 func sysUsed(v unsafe.Pointer, n uintptr) {
127 if debug.harddecommit > 0 {
128 p, err := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
129 if err == _ENOMEM {
130 throw("runtime: out of memory")
131 }
132 if p != v || err != 0 {
133 throw("runtime: cannot remap pages in address space")
134 }
135 return
136
137
138
139 }
140
141
142
143
144
145
146
147
148 sysHugePage(v, n)
149 }
150
151 func sysHugePage(v unsafe.Pointer, n uintptr) {
152 if physHugePageSize != 0 {
153
154 beg := alignUp(uintptr(v), physHugePageSize)
155
156 end := alignDown(uintptr(v)+n, physHugePageSize)
157
158 if beg < end {
159 madvise(unsafe.Pointer(beg), end-beg, _MADV_HUGEPAGE)
160 }
161 }
162 }
163
164
165
166
167 func sysFree(v unsafe.Pointer, n uintptr, sysStat *sysMemStat) {
168 sysStat.add(-int64(n))
169 munmap(v, n)
170 }
171
172 func sysFault(v unsafe.Pointer, n uintptr) {
173 mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE|_MAP_FIXED, -1, 0)
174 }
175
176 func sysReserve(v unsafe.Pointer, n uintptr) unsafe.Pointer {
177 p, err := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
178 if err != 0 {
179 return nil
180 }
181 return p
182 }
183
184 func sysMap(v unsafe.Pointer, n uintptr, sysStat *sysMemStat) {
185 sysStat.add(int64(n))
186
187 p, err := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
188 if err == _ENOMEM {
189 throw("runtime: out of memory")
190 }
191 if p != v || err != 0 {
192 print("runtime: mmap(", v, ", ", n, ") returned ", p, ", ", err, "\n")
193 throw("runtime: cannot map pages in arena address space")
194 }
195 }
196
View as plain text