Source file
src/runtime/os_openbsd.go
1
2
3
4
5 package runtime
6
7 import (
8 "internal/abi"
9 "internal/runtime/atomic"
10 "unsafe"
11 )
12
13 type mOS struct {
14 waitsemacount uint32
15 }
16
17 const (
18 _ESRCH = 3
19 _EWOULDBLOCK = _EAGAIN
20 _ENOTSUP = 91
21
22
23 _CLOCK_REALTIME = 0
24 _CLOCK_VIRTUAL = 1
25 _CLOCK_PROF = 2
26 _CLOCK_MONOTONIC = 3
27 )
28
29 type sigset uint32
30
31 var sigset_all = ^sigset(0)
32
33
34 const (
35 _CTL_HW = 6
36 _HW_NCPU = 3
37 _HW_PAGESIZE = 7
38 _HW_NCPUONLINE = 25
39 )
40
41 func sysctlInt(mib []uint32) (int32, bool) {
42 var out int32
43 nout := unsafe.Sizeof(out)
44 ret := sysctl(&mib[0], uint32(len(mib)), (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
45 if ret < 0 {
46 return 0, false
47 }
48 return out, true
49 }
50
51 func sysctlUint64(mib []uint32) (uint64, bool) {
52 var out uint64
53 nout := unsafe.Sizeof(out)
54 ret := sysctl(&mib[0], uint32(len(mib)), (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
55 if ret < 0 {
56 return 0, false
57 }
58 return out, true
59 }
60
61
62 func internal_cpu_sysctlUint64(mib []uint32) (uint64, bool) {
63 return sysctlUint64(mib)
64 }
65
66 func getCPUCount() int32 {
67
68
69
70 if n, ok := sysctlInt([]uint32{_CTL_HW, _HW_NCPUONLINE}); ok {
71 return int32(n)
72 }
73 if n, ok := sysctlInt([]uint32{_CTL_HW, _HW_NCPU}); ok {
74 return int32(n)
75 }
76 return 1
77 }
78
79 func getPageSize() uintptr {
80 if ps, ok := sysctlInt([]uint32{_CTL_HW, _HW_PAGESIZE}); ok {
81 return uintptr(ps)
82 }
83 return 0
84 }
85
86
87 func semacreate(mp *m) {
88 }
89
90
91 func semasleep(ns int64) int32 {
92 gp := getg()
93
94
95 var tsp *timespec
96 if ns >= 0 {
97 var ts timespec
98 ts.setNsec(ns + nanotime())
99 tsp = &ts
100 }
101
102 for {
103 v := atomic.Load(&gp.m.waitsemacount)
104 if v > 0 {
105 if atomic.Cas(&gp.m.waitsemacount, v, v-1) {
106 return 0
107 }
108 continue
109 }
110
111
112
113
114
115
116
117
118 ret := thrsleep(uintptr(unsafe.Pointer(&gp.m.waitsemacount)), _CLOCK_MONOTONIC, tsp, 0, &gp.m.waitsemacount)
119 if ret == _EWOULDBLOCK {
120 return -1
121 }
122 }
123 }
124
125
126 func semawakeup(mp *m) {
127 atomic.Xadd(&mp.waitsemacount, 1)
128 ret := thrwakeup(uintptr(unsafe.Pointer(&mp.waitsemacount)), 1)
129 if ret != 0 && ret != _ESRCH {
130
131 systemstack(func() {
132 print("thrwakeup addr=", &mp.waitsemacount, " sem=", mp.waitsemacount, " ret=", ret, "\n")
133 })
134 }
135 }
136
137
138 func mstart_stub()
139
140
141
142
143 func newosproc(mp *m) {
144 if false {
145 print("newosproc m=", mp, " g=", mp.g0, " id=", mp.id, " ostk=", &mp, "\n")
146 }
147
148
149 var attr pthreadattr
150 if err := pthread_attr_init(&attr); err != 0 {
151 writeErrStr(failthreadcreate)
152 exit(1)
153 }
154
155
156 var stacksize uintptr
157 if pthread_attr_getstacksize(&attr, &stacksize) != 0 {
158 writeErrStr(failthreadcreate)
159 exit(1)
160 }
161 mp.g0.stack.hi = stacksize
162
163
164 if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
165 writeErrStr(failthreadcreate)
166 exit(1)
167 }
168
169
170
171 var oset sigset
172 sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
173 err := retryOnEAGAIN(func() int32 {
174 return pthread_create(&attr, abi.FuncPCABI0(mstart_stub), unsafe.Pointer(mp))
175 })
176 sigprocmask(_SIG_SETMASK, &oset, nil)
177 if err != 0 {
178 writeErrStr(failthreadcreate)
179 exit(1)
180 }
181
182 pthread_attr_destroy(&attr)
183 }
184
185 func osinit() {
186 numCPUStartup = getCPUCount()
187 physPageSize = getPageSize()
188 }
189
190
191
192
193 var urandom_dev = []byte("/dev/urandom\x00")
194
195
196 func readRandom(r []byte) int {
197 fd := open(&urandom_dev[0], 0 , 0)
198 n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
199 closefd(fd)
200 return int(n)
201 }
202
203 func goenvs() {
204 goenvs_unix()
205 }
206
207
208
209 func mpreinit(mp *m) {
210 gsignalSize := int32(32 * 1024)
211 mp.gsignal = malg(gsignalSize)
212 mp.gsignal.m = mp
213 }
214
215
216
217 func minit() {
218 getg().m.procid = uint64(getthrid())
219 minitSignals()
220 }
221
222
223
224
225 func unminit() {
226 unminitSignals()
227 getg().m.procid = 0
228 }
229
230
231
232
233
234
235
236 func mdestroy(mp *m) {
237 }
238
239 func sigtramp()
240
241 type sigactiont struct {
242 sa_sigaction uintptr
243 sa_mask uint32
244 sa_flags int32
245 }
246
247
248
249 func setsig(i uint32, fn uintptr) {
250 var sa sigactiont
251 sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK | _SA_RESTART
252 sa.sa_mask = uint32(sigset_all)
253 if fn == abi.FuncPCABIInternal(sighandler) {
254 fn = abi.FuncPCABI0(sigtramp)
255 }
256 sa.sa_sigaction = fn
257 sigaction(i, &sa, nil)
258 }
259
260
261
262 func setsigstack(i uint32) {
263 throw("setsigstack")
264 }
265
266
267
268 func getsig(i uint32) uintptr {
269 var sa sigactiont
270 sigaction(i, nil, &sa)
271 return sa.sa_sigaction
272 }
273
274
275
276
277 func setSignalstackSP(s *stackt, sp uintptr) {
278 s.ss_sp = sp
279 }
280
281
282
283 func sigaddset(mask *sigset, i int) {
284 *mask |= 1 << (uint32(i) - 1)
285 }
286
287 func sigdelset(mask *sigset, i int) {
288 *mask &^= 1 << (uint32(i) - 1)
289 }
290
291
292 func (c *sigctxt) fixsigcode(sig uint32) {
293 }
294
295 func setProcessCPUProfiler(hz int32) {
296 setProcessCPUProfilerTimer(hz)
297 }
298
299 func setThreadCPUProfiler(hz int32) {
300 setThreadCPUProfilerHz(hz)
301 }
302
303
304 func validSIGPROF(mp *m, c *sigctxt) bool {
305 return true
306 }
307
308 func osStackAlloc(s *mspan) {
309 osStackRemap(s, _MAP_STACK)
310 }
311
312 func osStackFree(s *mspan) {
313
314 osStackRemap(s, 0)
315 }
316
317 func osStackRemap(s *mspan, flags int32) {
318 a, err := mmap(unsafe.Pointer(s.base()), s.npages*pageSize, _PROT_READ|_PROT_WRITE, _MAP_PRIVATE|_MAP_ANON|_MAP_FIXED|flags, -1, 0)
319 if err != 0 || uintptr(a) != s.base() {
320 print("runtime: remapping stack memory ", hex(s.base()), " ", s.npages*pageSize, " a=", a, " err=", err, "\n")
321 throw("remapping stack memory failed")
322 }
323 }
324
325
326 func raise(sig uint32) {
327 thrkill(getthrid(), int(sig))
328 }
329
330 func signalM(mp *m, sig int) {
331 thrkill(int32(mp.procid), sig)
332 }
333
334
335
336 const sigPerThreadSyscall = 1 << 31
337
338
339 func runPerThreadSyscall() {
340 throw("runPerThreadSyscall only valid on linux")
341 }
342
View as plain text