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 getncpu() 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 ncpu = getncpu()
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 func mdestroy(mp *m) {
326 }
327
328 func sigtramp()
329
330 type sigactiont struct {
331 sa_sigaction uintptr
332 sa_mask sigset
333 sa_flags int32
334 }
335
336
337
338 func setsig(i uint32, fn uintptr) {
339 var sa sigactiont
340 sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK | _SA_RESTART
341 sa.sa_mask = sigset_all
342 if fn == abi.FuncPCABIInternal(sighandler) {
343 fn = abi.FuncPCABI0(sigtramp)
344 }
345 sa.sa_sigaction = fn
346 sigaction(i, &sa, nil)
347 }
348
349
350
351 func setsigstack(i uint32) {
352 throw("setsigstack")
353 }
354
355
356
357 func getsig(i uint32) uintptr {
358 var sa sigactiont
359 sigaction(i, nil, &sa)
360 return sa.sa_sigaction
361 }
362
363
364
365
366 func setSignalstackSP(s *stackt, sp uintptr) {
367 s.ss_sp = sp
368 }
369
370
371
372 func sigaddset(mask *sigset, i int) {
373 mask.__bits[(i-1)/32] |= 1 << ((uint32(i) - 1) & 31)
374 }
375
376 func sigdelset(mask *sigset, i int) {
377 mask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
378 }
379
380
381 func (c *sigctxt) fixsigcode(sig uint32) {
382 }
383
384 func setProcessCPUProfiler(hz int32) {
385 setProcessCPUProfilerTimer(hz)
386 }
387
388 func setThreadCPUProfiler(hz int32) {
389 setThreadCPUProfilerHz(hz)
390 }
391
392
393 func validSIGPROF(mp *m, c *sigctxt) bool {
394 return true
395 }
396
397 func sysargs(argc int32, argv **byte) {
398 n := argc + 1
399
400
401 for argv_index(argv, n) != nil {
402 n++
403 }
404
405
406 n++
407
408
409 auxvp := (*[1 << 28]uintptr)(add(unsafe.Pointer(argv), uintptr(n)*goarch.PtrSize))
410 pairs := sysauxv(auxvp[:])
411 auxv = auxvp[: pairs*2 : pairs*2]
412 }
413
414 const (
415 _AT_NULL = 0
416 _AT_PAGESZ = 6
417 )
418
419 func sysauxv(auxv []uintptr) (pairs int) {
420 var i int
421 for i = 0; auxv[i] != _AT_NULL; i += 2 {
422 tag, val := auxv[i], auxv[i+1]
423 switch tag {
424 case _AT_PAGESZ:
425 physPageSize = val
426 }
427 }
428 return i / 2
429 }
430
431
432
433
434
435
436
437 func raise(sig uint32) {
438 lwp_kill(lwp_self(), int(sig))
439 }
440
441 func signalM(mp *m, sig int) {
442 lwp_kill(int32(mp.procid), sig)
443 }
444
445
446
447 const sigPerThreadSyscall = 1 << 31
448
449
450 func runPerThreadSyscall() {
451 throw("runPerThreadSyscall only valid on linux")
452 }
453
View as plain text