Source file
src/runtime/os_netbsd.go
1
2
3
4
5 package runtime
6
7 import (
8 "internal/abi"
9 "internal/goarch"
10 "internal/runtime/atomic"
11 "unsafe"
12 )
13
14 const (
15 _SS_DISABLE = 4
16 _SIG_BLOCK = 1
17 _SIG_UNBLOCK = 2
18 _SIG_SETMASK = 3
19 _NSIG = 33
20 _SI_USER = 0
21
22
23 _UC_SIGMASK = 0x01
24 _UC_CPU = 0x04
25
26
27 _LWP_DETACHED = 0x00000040
28 )
29
30 type mOS struct {
31 waitsemacount uint32
32 }
33
34
35 func setitimer(mode int32, new, old *itimerval)
36
37
38 func sigaction(sig uint32, new, old *sigactiont)
39
40
41 func sigaltstack(new, old *stackt)
42
43
44 func sigprocmask(how int32, new, old *sigset)
45
46
47 func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
48
49 func lwp_tramp()
50
51 func raiseproc(sig uint32)
52
53 func lwp_kill(tid int32, sig int)
54
55
56 func getcontext(ctxt unsafe.Pointer)
57
58
59 func lwp_create(ctxt unsafe.Pointer, flags uintptr, lwpid unsafe.Pointer) int32
60
61
62 func lwp_park(clockid, flags int32, ts *timespec, unpark int32, hint, unparkhint unsafe.Pointer) int32
63
64
65 func lwp_unpark(lwp int32, hint unsafe.Pointer) int32
66
67 func lwp_self() int32
68
69 func osyield()
70
71
72 func osyield_no_g() {
73 osyield()
74 }
75
76 func kqueue() int32
77
78
79 func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
80
81 func pipe2(flags int32) (r, w int32, errno int32)
82 func fcntl(fd, cmd, arg int32) (ret int32, errno int32)
83
84 func issetugid() int32
85
86 const (
87 _ESRCH = 3
88 _ETIMEDOUT = 60
89
90
91 _CLOCK_REALTIME = 0
92 _CLOCK_VIRTUAL = 1
93 _CLOCK_PROF = 2
94 _CLOCK_MONOTONIC = 3
95
96 _TIMER_RELTIME = 0
97 _TIMER_ABSTIME = 1
98 )
99
100 var sigset_all = sigset{[4]uint32{^uint32(0), ^uint32(0), ^uint32(0), ^uint32(0)}}
101
102
103 const (
104 _CTL_KERN = 1
105 _KERN_OSREV = 3
106
107 _CTL_HW = 6
108 _HW_NCPU = 3
109 _HW_PAGESIZE = 7
110 _HW_NCPUONLINE = 16
111 )
112
113 func sysctlInt(mib []uint32) (int32, bool) {
114 var out int32
115 nout := unsafe.Sizeof(out)
116 ret := sysctl(&mib[0], uint32(len(mib)), (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
117 if ret < 0 {
118 return 0, false
119 }
120 return out, true
121 }
122
123 func getCPUCount() int32 {
124 if n, ok := sysctlInt([]uint32{_CTL_HW, _HW_NCPUONLINE}); ok {
125 return int32(n)
126 }
127 if n, ok := sysctlInt([]uint32{_CTL_HW, _HW_NCPU}); ok {
128 return int32(n)
129 }
130 return 1
131 }
132
133 func getPageSize() uintptr {
134 mib := [2]uint32{_CTL_HW, _HW_PAGESIZE}
135 out := uint32(0)
136 nout := unsafe.Sizeof(out)
137 ret := sysctl(&mib[0], 2, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
138 if ret >= 0 {
139 return uintptr(out)
140 }
141 return 0
142 }
143
144 func getOSRev() int {
145 if osrev, ok := sysctlInt([]uint32{_CTL_KERN, _KERN_OSREV}); ok {
146 return int(osrev)
147 }
148 return 0
149 }
150
151
152 func semacreate(mp *m) {
153 }
154
155
156 func semasleep(ns int64) int32 {
157 gp := getg()
158 var deadline int64
159 if ns >= 0 {
160 deadline = nanotime() + ns
161 }
162
163 for {
164 v := atomic.Load(&gp.m.waitsemacount)
165 if v > 0 {
166 if atomic.Cas(&gp.m.waitsemacount, v, v-1) {
167 return 0
168 }
169 continue
170 }
171
172
173 var tsp *timespec
174 var ts timespec
175 if ns >= 0 {
176 wait := deadline - nanotime()
177 if wait <= 0 {
178 return -1
179 }
180 ts.setNsec(wait)
181 tsp = &ts
182 }
183 ret := lwp_park(_CLOCK_MONOTONIC, _TIMER_RELTIME, tsp, 0, unsafe.Pointer(&gp.m.waitsemacount), nil)
184 if ret == _ETIMEDOUT {
185 return -1
186 }
187 }
188 }
189
190
191 func semawakeup(mp *m) {
192 atomic.Xadd(&mp.waitsemacount, 1)
193
194
195
196 ret := lwp_unpark(int32(mp.procid), unsafe.Pointer(&mp.waitsemacount))
197 if ret != 0 && ret != _ESRCH {
198
199 systemstack(func() {
200 print("thrwakeup addr=", &mp.waitsemacount, " sem=", mp.waitsemacount, " ret=", ret, "\n")
201 })
202 }
203 }
204
205
206
207
208 func newosproc(mp *m) {
209 stk := unsafe.Pointer(mp.g0.stack.hi)
210 if false {
211 print("newosproc stk=", stk, " m=", mp, " g=", mp.g0, " id=", mp.id, " ostk=", &mp, "\n")
212 }
213
214 var uc ucontextt
215 getcontext(unsafe.Pointer(&uc))
216
217
218
219
220
221
222
223 uc.uc_flags = _UC_SIGMASK | _UC_CPU
224 uc.uc_link = nil
225 uc.uc_sigmask = sigset_all
226
227 var oset sigset
228 sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
229
230 lwp_mcontext_init(&uc.uc_mcontext, stk, mp, mp.g0, abi.FuncPCABI0(netbsdMstart))
231
232 ret := retryOnEAGAIN(func() int32 {
233 errno := lwp_create(unsafe.Pointer(&uc), _LWP_DETACHED, unsafe.Pointer(&mp.procid))
234
235 return -errno
236 })
237 sigprocmask(_SIG_SETMASK, &oset, nil)
238 if ret != 0 {
239 print("runtime: failed to create new OS thread (have ", mcount()-1, " already; errno=", ret, ")\n")
240 if ret == _EAGAIN {
241 println("runtime: may need to increase max user processes (ulimit -p)")
242 }
243 throw("runtime.newosproc")
244 }
245 }
246
247
248
249 func netbsdMstart()
250
251
252
253
254
255
256
257
258
259
260 func netbsdMstart0() {
261 st := stackt{ss_flags: _SS_DISABLE}
262 sigaltstack(&st, nil)
263 mstart0()
264 }
265
266 func osinit() {
267 numCPUStartup = getCPUCount()
268 if physPageSize == 0 {
269 physPageSize = getPageSize()
270 }
271 needSysmonWorkaround = getOSRev() < 902000000
272 }
273
274 var urandom_dev = []byte("/dev/urandom\x00")
275
276
277 func readRandom(r []byte) int {
278 fd := open(&urandom_dev[0], 0 , 0)
279 n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
280 closefd(fd)
281 return int(n)
282 }
283
284 func goenvs() {
285 goenvs_unix()
286 }
287
288
289
290 func mpreinit(mp *m) {
291 mp.gsignal = malg(32 * 1024)
292 mp.gsignal.m = mp
293 }
294
295
296
297 func minit() {
298 gp := getg()
299 gp.m.procid = uint64(lwp_self())
300
301
302
303
304
305
306
307
308 signalstack(&gp.m.gsignal.stack)
309 gp.m.newSigstack = true
310
311 minitSignalMask()
312 }
313
314
315
316
317 func unminit() {
318 unminitSignals()
319
320
321 }
322
323
324
325
326
327
328
329 func mdestroy(mp *m) {
330 }
331
332 func sigtramp()
333
334 type sigactiont struct {
335 sa_sigaction uintptr
336 sa_mask sigset
337 sa_flags int32
338 }
339
340
341
342 func setsig(i uint32, fn uintptr) {
343 var sa sigactiont
344 sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK | _SA_RESTART
345 sa.sa_mask = sigset_all
346 if fn == abi.FuncPCABIInternal(sighandler) {
347 fn = abi.FuncPCABI0(sigtramp)
348 }
349 sa.sa_sigaction = fn
350 sigaction(i, &sa, nil)
351 }
352
353
354
355 func setsigstack(i uint32) {
356 throw("setsigstack")
357 }
358
359
360
361 func getsig(i uint32) uintptr {
362 var sa sigactiont
363 sigaction(i, nil, &sa)
364 return sa.sa_sigaction
365 }
366
367
368
369
370 func setSignalstackSP(s *stackt, sp uintptr) {
371 s.ss_sp = sp
372 }
373
374
375
376 func sigaddset(mask *sigset, i int) {
377 mask.__bits[(i-1)/32] |= 1 << ((uint32(i) - 1) & 31)
378 }
379
380 func sigdelset(mask *sigset, i int) {
381 mask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
382 }
383
384
385 func (c *sigctxt) fixsigcode(sig uint32) {
386 }
387
388 func setProcessCPUProfiler(hz int32) {
389 setProcessCPUProfilerTimer(hz)
390 }
391
392 func setThreadCPUProfiler(hz int32) {
393 setThreadCPUProfilerHz(hz)
394 }
395
396
397 func validSIGPROF(mp *m, c *sigctxt) bool {
398 return true
399 }
400
401 func sysargs(argc int32, argv **byte) {
402 n := argc + 1
403
404
405 for argv_index(argv, n) != nil {
406 n++
407 }
408
409
410 n++
411
412
413 auxvp := (*[1 << 28]uintptr)(add(unsafe.Pointer(argv), uintptr(n)*goarch.PtrSize))
414 pairs := sysauxv(auxvp[:])
415 auxv = auxvp[: pairs*2 : pairs*2]
416 }
417
418 const (
419 _AT_NULL = 0
420 _AT_PAGESZ = 6
421 )
422
423 func sysauxv(auxv []uintptr) (pairs int) {
424 var i int
425 for i = 0; auxv[i] != _AT_NULL; i += 2 {
426 tag, val := auxv[i], auxv[i+1]
427 switch tag {
428 case _AT_PAGESZ:
429 physPageSize = val
430 }
431 }
432 return i / 2
433 }
434
435
436
437
438
439
440
441 func raise(sig uint32) {
442 lwp_kill(lwp_self(), int(sig))
443 }
444
445 func signalM(mp *m, sig int) {
446 lwp_kill(int32(mp.procid), sig)
447 }
448
449
450
451 const sigPerThreadSyscall = 1 << 31
452
453
454 func runPerThreadSyscall() {
455 throw("runPerThreadSyscall only valid on linux")
456 }
457
View as plain text