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