Source file
src/runtime/os3_solaris.go
Documentation: runtime
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
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 var (
89 libc____errno,
90 libc_clock_gettime,
91 libc_exit,
92 libc_getcontext,
93 libc_kill,
94 libc_madvise,
95 libc_malloc,
96 libc_mmap,
97 libc_munmap,
98 libc_open,
99 libc_pthread_attr_destroy,
100 libc_pthread_attr_getstack,
101 libc_pthread_attr_init,
102 libc_pthread_attr_setdetachstate,
103 libc_pthread_attr_setstack,
104 libc_pthread_create,
105 libc_pthread_self,
106 libc_pthread_kill,
107 libc_raise,
108 libc_read,
109 libc_sched_yield,
110 libc_select,
111 libc_sem_init,
112 libc_sem_post,
113 libc_sem_reltimedwait_np,
114 libc_sem_wait,
115 libc_setitimer,
116 libc_sigaction,
117 libc_sigaltstack,
118 libc_sigprocmask,
119 libc_sysconf,
120 libc_usleep,
121 libc_write,
122 libc_pipe2 libcFunc
123 )
124
125 var sigset_all = sigset{[4]uint32{^uint32(0), ^uint32(0), ^uint32(0), ^uint32(0)}}
126
127 func getPageSize() uintptr {
128 n := int32(sysconf(__SC_PAGESIZE))
129 if n <= 0 {
130 return 0
131 }
132 return uintptr(n)
133 }
134
135 func osinit() {
136
137
138 asmcgocall(unsafe.Pointer(abi.FuncPCABI0(miniterrno)), unsafe.Pointer(&libc____errno))
139
140 ncpu = getncpu()
141 if physPageSize == 0 {
142 physPageSize = getPageSize()
143 }
144 }
145
146 func tstart_sysvicall(newm *m) uint32
147
148
149
150
151 func newosproc(mp *m) {
152 var (
153 attr pthreadattr
154 oset sigset
155 tid pthread
156 ret int32
157 size uint64
158 )
159
160 if pthread_attr_init(&attr) != 0 {
161 throw("pthread_attr_init")
162 }
163
164 if pthread_attr_setstack(&attr, 0, 0x200000) != 0 {
165 throw("pthread_attr_setstack")
166 }
167
168 if pthread_attr_getstack(&attr, unsafe.Pointer(&mp.g0.stack.hi), &size) != 0 {
169 throw("pthread_attr_getstack")
170 }
171 mp.g0.stack.lo = mp.g0.stack.hi - uintptr(size)
172 if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
173 throw("pthread_attr_setdetachstate")
174 }
175
176
177
178 sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
179 ret = retryOnEAGAIN(func() int32 {
180 return pthread_create(&tid, &attr, abi.FuncPCABI0(tstart_sysvicall), unsafe.Pointer(mp))
181 })
182 sigprocmask(_SIG_SETMASK, &oset, nil)
183 if ret != 0 {
184 print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", ret, ")\n")
185 if ret == _EAGAIN {
186 println("runtime: may need to increase max user processes (ulimit -u)")
187 }
188 throw("newosproc")
189 }
190 }
191
192 func exitThread(wait *atomic.Uint32) {
193
194
195 throw("exitThread")
196 }
197
198 var urandom_dev = []byte("/dev/urandom\x00")
199
200
201 func readRandom(r []byte) int {
202 fd := open(&urandom_dev[0], 0 , 0)
203 n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
204 closefd(fd)
205 return int(n)
206 }
207
208 func goenvs() {
209 goenvs_unix()
210 }
211
212
213
214 func mpreinit(mp *m) {
215 mp.gsignal = malg(32 * 1024)
216 mp.gsignal.m = mp
217 }
218
219 func miniterrno()
220
221
222
223 func minit() {
224 asmcgocall(unsafe.Pointer(abi.FuncPCABI0(miniterrno)), unsafe.Pointer(&libc____errno))
225
226 minitSignals()
227
228 getg().m.procid = uint64(pthread_self())
229 }
230
231
232 func unminit() {
233 unminitSignals()
234 getg().m.procid = 0
235 }
236
237
238
239 func mdestroy(mp *m) {
240 }
241
242 func sigtramp()
243
244
245
246 func setsig(i uint32, fn uintptr) {
247 var sa sigactiont
248
249 sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK | _SA_RESTART
250 sa.sa_mask = sigset_all
251 if fn == abi.FuncPCABIInternal(sighandler) {
252 fn = abi.FuncPCABI0(sigtramp)
253 }
254 *((*uintptr)(unsafe.Pointer(&sa._funcptr))) = fn
255 sigaction(i, &sa, nil)
256 }
257
258
259
260 func setsigstack(i uint32) {
261 var sa sigactiont
262 sigaction(i, nil, &sa)
263 if sa.sa_flags&_SA_ONSTACK != 0 {
264 return
265 }
266 sa.sa_flags |= _SA_ONSTACK
267 sigaction(i, &sa, nil)
268 }
269
270
271
272 func getsig(i uint32) uintptr {
273 var sa sigactiont
274 sigaction(i, nil, &sa)
275 return *((*uintptr)(unsafe.Pointer(&sa._funcptr)))
276 }
277
278
279
280
281 func setSignalstackSP(s *stackt, sp uintptr) {
282 *(*uintptr)(unsafe.Pointer(&s.ss_sp)) = sp
283 }
284
285
286
287 func sigaddset(mask *sigset, i int) {
288 mask.__sigbits[(i-1)/32] |= 1 << ((uint32(i) - 1) & 31)
289 }
290
291 func sigdelset(mask *sigset, i int) {
292 mask.__sigbits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
293 }
294
295
296 func (c *sigctxt) fixsigcode(sig uint32) {
297 }
298
299 func setProcessCPUProfiler(hz int32) {
300 setProcessCPUProfilerTimer(hz)
301 }
302
303 func setThreadCPUProfiler(hz int32) {
304 setThreadCPUProfilerHz(hz)
305 }
306
307
308 func validSIGPROF(mp *m, c *sigctxt) bool {
309 return true
310 }
311
312
313 func semacreate(mp *m) {
314 if mp.waitsema != 0 {
315 return
316 }
317
318 var sem *semt
319
320
321
322
323 mp.libcall.fn = uintptr(unsafe.Pointer(&libc_malloc))
324 mp.libcall.n = 1
325 mp.scratch = mscratch{}
326 mp.scratch.v[0] = unsafe.Sizeof(*sem)
327 mp.libcall.args = uintptr(unsafe.Pointer(&mp.scratch))
328 asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&mp.libcall))
329 sem = (*semt)(unsafe.Pointer(mp.libcall.r1))
330 if sem_init(sem, 0, 0) != 0 {
331 throw("sem_init")
332 }
333 mp.waitsema = uintptr(unsafe.Pointer(sem))
334 }
335
336
337 func semasleep(ns int64) int32 {
338 mp := getg().m
339 if ns >= 0 {
340 mp.ts.tv_sec = ns / 1000000000
341 mp.ts.tv_nsec = ns % 1000000000
342
343 mp.libcall.fn = uintptr(unsafe.Pointer(&libc_sem_reltimedwait_np))
344 mp.libcall.n = 2
345 mp.scratch = mscratch{}
346 mp.scratch.v[0] = mp.waitsema
347 mp.scratch.v[1] = uintptr(unsafe.Pointer(&mp.ts))
348 mp.libcall.args = uintptr(unsafe.Pointer(&mp.scratch))
349 asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&mp.libcall))
350 if *mp.perrno != 0 {
351 if *mp.perrno == _ETIMEDOUT || *mp.perrno == _EAGAIN || *mp.perrno == _EINTR {
352 return -1
353 }
354 throw("sem_reltimedwait_np")
355 }
356 return 0
357 }
358 for {
359 mp.libcall.fn = uintptr(unsafe.Pointer(&libc_sem_wait))
360 mp.libcall.n = 1
361 mp.scratch = mscratch{}
362 mp.scratch.v[0] = mp.waitsema
363 mp.libcall.args = uintptr(unsafe.Pointer(&mp.scratch))
364 asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&mp.libcall))
365 if mp.libcall.r1 == 0 {
366 break
367 }
368 if *mp.perrno == _EINTR {
369 continue
370 }
371 throw("sem_wait")
372 }
373 return 0
374 }
375
376
377 func semawakeup(mp *m) {
378 if sem_post((*semt)(unsafe.Pointer(mp.waitsema))) != 0 {
379 throw("sem_post")
380 }
381 }
382
383
384 func closefd(fd int32) int32 {
385 return int32(sysvicall1(&libc_close, uintptr(fd)))
386 }
387
388
389 func exit(r int32) {
390 sysvicall1(&libc_exit, uintptr(r))
391 }
392
393
394 func getcontext(context *ucontext) {
395 sysvicall1(&libc_getcontext, uintptr(unsafe.Pointer(context)))
396 }
397
398
399 func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
400 sysvicall3(&libc_madvise, uintptr(addr), uintptr(n), uintptr(flags))
401 }
402
403
404 func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (unsafe.Pointer, int) {
405 p, err := doMmap(uintptr(addr), n, uintptr(prot), uintptr(flags), uintptr(fd), uintptr(off))
406 if p == ^uintptr(0) {
407 return nil, int(err)
408 }
409 return unsafe.Pointer(p), 0
410 }
411
412
413
414 func doMmap(addr, n, prot, flags, fd, off uintptr) (uintptr, uintptr) {
415 var libcall libcall
416 libcall.fn = uintptr(unsafe.Pointer(&libc_mmap))
417 libcall.n = 6
418 libcall.args = uintptr(noescape(unsafe.Pointer(&addr)))
419 asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
420 return libcall.r1, libcall.err
421 }
422
423
424 func munmap(addr unsafe.Pointer, n uintptr) {
425 sysvicall2(&libc_munmap, uintptr(addr), uintptr(n))
426 }
427
428 const (
429 _CLOCK_REALTIME = 3
430 _CLOCK_MONOTONIC = 4
431 )
432
433
434 func nanotime1() int64 {
435 var ts mts
436 sysvicall2(&libc_clock_gettime, _CLOCK_MONOTONIC, uintptr(unsafe.Pointer(&ts)))
437 return ts.tv_sec*1e9 + ts.tv_nsec
438 }
439
440
441 func open(path *byte, mode, perm int32) int32 {
442 return int32(sysvicall3(&libc_open, uintptr(unsafe.Pointer(path)), uintptr(mode), uintptr(perm)))
443 }
444
445 func pthread_attr_destroy(attr *pthreadattr) int32 {
446 return int32(sysvicall1(&libc_pthread_attr_destroy, uintptr(unsafe.Pointer(attr))))
447 }
448
449 func pthread_attr_getstack(attr *pthreadattr, addr unsafe.Pointer, size *uint64) int32 {
450 return int32(sysvicall3(&libc_pthread_attr_getstack, uintptr(unsafe.Pointer(attr)), uintptr(addr), uintptr(unsafe.Pointer(size))))
451 }
452
453 func pthread_attr_init(attr *pthreadattr) int32 {
454 return int32(sysvicall1(&libc_pthread_attr_init, uintptr(unsafe.Pointer(attr))))
455 }
456
457 func pthread_attr_setdetachstate(attr *pthreadattr, state int32) int32 {
458 return int32(sysvicall2(&libc_pthread_attr_setdetachstate, uintptr(unsafe.Pointer(attr)), uintptr(state)))
459 }
460
461 func pthread_attr_setstack(attr *pthreadattr, addr uintptr, size uint64) int32 {
462 return int32(sysvicall3(&libc_pthread_attr_setstack, uintptr(unsafe.Pointer(attr)), uintptr(addr), uintptr(size)))
463 }
464
465 func pthread_create(thread *pthread, attr *pthreadattr, fn uintptr, arg unsafe.Pointer) int32 {
466 return int32(sysvicall4(&libc_pthread_create, uintptr(unsafe.Pointer(thread)), uintptr(unsafe.Pointer(attr)), uintptr(fn), uintptr(arg)))
467 }
468
469 func pthread_self() pthread {
470 return pthread(sysvicall0(&libc_pthread_self))
471 }
472
473 func signalM(mp *m, sig int) {
474 sysvicall2(&libc_pthread_kill, uintptr(pthread(mp.procid)), uintptr(sig))
475 }
476
477
478
479 func raise(sig uint32) {
480 sysvicall1(&libc_raise, uintptr(sig))
481 }
482
483 func raiseproc(sig uint32) {
484 pid := sysvicall0(&libc_getpid)
485 sysvicall2(&libc_kill, pid, uintptr(sig))
486 }
487
488
489 func read(fd int32, buf unsafe.Pointer, nbyte int32) int32 {
490 r1, err := sysvicall3Err(&libc_read, uintptr(fd), uintptr(buf), uintptr(nbyte))
491 if c := int32(r1); c >= 0 {
492 return c
493 }
494 return -int32(err)
495 }
496
497
498 func sem_init(sem *semt, pshared int32, value uint32) int32 {
499 return int32(sysvicall3(&libc_sem_init, uintptr(unsafe.Pointer(sem)), uintptr(pshared), uintptr(value)))
500 }
501
502
503 func sem_post(sem *semt) int32 {
504 return int32(sysvicall1(&libc_sem_post, uintptr(unsafe.Pointer(sem))))
505 }
506
507
508 func sem_reltimedwait_np(sem *semt, timeout *timespec) int32 {
509 return int32(sysvicall2(&libc_sem_reltimedwait_np, uintptr(unsafe.Pointer(sem)), uintptr(unsafe.Pointer(timeout))))
510 }
511
512
513 func sem_wait(sem *semt) int32 {
514 return int32(sysvicall1(&libc_sem_wait, uintptr(unsafe.Pointer(sem))))
515 }
516
517 func setitimer(which int32, value *itimerval, ovalue *itimerval) {
518 sysvicall3(&libc_setitimer, uintptr(which), uintptr(unsafe.Pointer(value)), uintptr(unsafe.Pointer(ovalue)))
519 }
520
521
522
523 func sigaction(sig uint32, act *sigactiont, oact *sigactiont) {
524 sysvicall3(&libc_sigaction, uintptr(sig), uintptr(unsafe.Pointer(act)), uintptr(unsafe.Pointer(oact)))
525 }
526
527
528
529 func sigaltstack(ss *stackt, oss *stackt) {
530 sysvicall2(&libc_sigaltstack, uintptr(unsafe.Pointer(ss)), uintptr(unsafe.Pointer(oss)))
531 }
532
533
534
535 func sigprocmask(how int32, set *sigset, oset *sigset) {
536 sysvicall3(&libc_sigprocmask, uintptr(how), uintptr(unsafe.Pointer(set)), uintptr(unsafe.Pointer(oset)))
537 }
538
539 func sysconf(name int32) int64 {
540 return int64(sysvicall1(&libc_sysconf, uintptr(name)))
541 }
542
543 func usleep1(usec uint32)
544
545
546 func usleep_no_g(µs uint32) {
547 usleep1(µs)
548 }
549
550
551 func usleep(µs uint32) {
552 usleep1(µs)
553 }
554
555 func walltime() (sec int64, nsec int32) {
556 var ts mts
557 sysvicall2(&libc_clock_gettime, _CLOCK_REALTIME, uintptr(unsafe.Pointer(&ts)))
558 return ts.tv_sec, int32(ts.tv_nsec)
559 }
560
561
562 func write1(fd uintptr, buf unsafe.Pointer, nbyte int32) int32 {
563 r1, err := sysvicall3Err(&libc_write, fd, uintptr(buf), uintptr(nbyte))
564 if c := int32(r1); c >= 0 {
565 return c
566 }
567 return -int32(err)
568 }
569
570
571 func pipe2(flags int32) (r, w int32, errno int32) {
572 var p [2]int32
573 _, e := sysvicall2Err(&libc_pipe2, uintptr(noescape(unsafe.Pointer(&p))), uintptr(flags))
574 return p[0], p[1], int32(e)
575 }
576
577
578 func fcntl(fd, cmd, arg int32) (ret int32, errno int32) {
579 r1, err := sysvicall3Err(&libc_fcntl, uintptr(fd), uintptr(cmd), uintptr(arg))
580 return int32(r1), int32(err)
581 }
582
583 func osyield1()
584
585
586 func osyield_no_g() {
587 osyield1()
588 }
589
590
591 func osyield() {
592 sysvicall0(&libc_sched_yield)
593 }
594
595
596 var executablePath string
597
598 func sysargs(argc int32, argv **byte) {
599 n := argc + 1
600
601
602 for argv_index(argv, n) != nil {
603 n++
604 }
605
606
607 n++
608
609
610 auxvp := (*[1 << 28]uintptr)(add(unsafe.Pointer(argv), uintptr(n)*goarch.PtrSize))
611 pairs := sysauxv(auxvp[:])
612 auxv = auxvp[: pairs*2 : pairs*2]
613 }
614
615 const (
616 _AT_NULL = 0
617 _AT_PAGESZ = 6
618 _AT_SUN_EXECNAME = 2014
619 )
620
621 func sysauxv(auxv []uintptr) (pairs int) {
622 var i int
623 for i = 0; auxv[i] != _AT_NULL; i += 2 {
624 tag, val := auxv[i], auxv[i+1]
625 switch tag {
626 case _AT_PAGESZ:
627 physPageSize = val
628 case _AT_SUN_EXECNAME:
629 executablePath = gostringnocopy((*byte)(unsafe.Pointer(val)))
630 }
631 }
632 return i / 2
633 }
634
635
636
637 const sigPerThreadSyscall = 1 << 31
638
639
640 func runPerThreadSyscall() {
641 throw("runPerThreadSyscall only valid on linux")
642 }
643
View as plain text