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