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