Source file
src/runtime/os3_solaris.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
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
240
241
242 func mdestroy(mp *m) {
243 }
244
245 func sigtramp()
246
247
248
249 func setsig(i uint32, fn uintptr) {
250 var sa sigactiont
251
252 sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK | _SA_RESTART
253 sa.sa_mask = sigset_all
254 if fn == abi.FuncPCABIInternal(sighandler) {
255 fn = abi.FuncPCABI0(sigtramp)
256 }
257 *((*uintptr)(unsafe.Pointer(&sa._funcptr))) = fn
258 sigaction(i, &sa, nil)
259 }
260
261
262
263 func setsigstack(i uint32) {
264 var sa sigactiont
265 sigaction(i, nil, &sa)
266 if sa.sa_flags&_SA_ONSTACK != 0 {
267 return
268 }
269 sa.sa_flags |= _SA_ONSTACK
270 sigaction(i, &sa, nil)
271 }
272
273
274
275 func getsig(i uint32) uintptr {
276 var sa sigactiont
277 sigaction(i, nil, &sa)
278 return *((*uintptr)(unsafe.Pointer(&sa._funcptr)))
279 }
280
281
282
283
284 func setSignalstackSP(s *stackt, sp uintptr) {
285 *(*uintptr)(unsafe.Pointer(&s.ss_sp)) = sp
286 }
287
288
289
290 func sigaddset(mask *sigset, i int) {
291 mask.__sigbits[(i-1)/32] |= 1 << ((uint32(i) - 1) & 31)
292 }
293
294 func sigdelset(mask *sigset, i int) {
295 mask.__sigbits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
296 }
297
298
299 func (c *sigctxt) fixsigcode(sig uint32) {
300 }
301
302 func setProcessCPUProfiler(hz int32) {
303 setProcessCPUProfilerTimer(hz)
304 }
305
306 func setThreadCPUProfiler(hz int32) {
307 setThreadCPUProfilerHz(hz)
308 }
309
310
311 func validSIGPROF(mp *m, c *sigctxt) bool {
312 return true
313 }
314
315
316 func semacreate(mp *m) {
317 if mp.waitsema != 0 {
318 return
319 }
320
321 var sem *semt
322
323
324
325
326 mp.libcall.fn = uintptr(unsafe.Pointer(&libc_malloc))
327 mp.libcall.n = 1
328 mp.scratch = mscratch{}
329 mp.scratch.v[0] = unsafe.Sizeof(*sem)
330 mp.libcall.args = uintptr(unsafe.Pointer(&mp.scratch))
331 asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&mp.libcall))
332 sem = (*semt)(unsafe.Pointer(mp.libcall.r1))
333 if sem_init(sem, 0, 0) != 0 {
334 throw("sem_init")
335 }
336 mp.waitsema = uintptr(unsafe.Pointer(sem))
337 }
338
339
340 func semasleep(ns int64) int32 {
341 mp := getg().m
342 if ns >= 0 {
343 mp.ts.tv_sec = ns / 1000000000
344 mp.ts.tv_nsec = ns % 1000000000
345
346 mp.libcall.fn = uintptr(unsafe.Pointer(&libc_sem_reltimedwait_np))
347 mp.libcall.n = 2
348 mp.scratch = mscratch{}
349 mp.scratch.v[0] = mp.waitsema
350 mp.scratch.v[1] = uintptr(unsafe.Pointer(&mp.ts))
351 mp.libcall.args = uintptr(unsafe.Pointer(&mp.scratch))
352 asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&mp.libcall))
353 if *mp.perrno != 0 {
354 if *mp.perrno == _ETIMEDOUT || *mp.perrno == _EAGAIN || *mp.perrno == _EINTR {
355 return -1
356 }
357 throw("sem_reltimedwait_np")
358 }
359 return 0
360 }
361 for {
362 mp.libcall.fn = uintptr(unsafe.Pointer(&libc_sem_wait))
363 mp.libcall.n = 1
364 mp.scratch = mscratch{}
365 mp.scratch.v[0] = mp.waitsema
366 mp.libcall.args = uintptr(unsafe.Pointer(&mp.scratch))
367 asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&mp.libcall))
368 if mp.libcall.r1 == 0 {
369 break
370 }
371 if *mp.perrno == _EINTR {
372 continue
373 }
374 throw("sem_wait")
375 }
376 return 0
377 }
378
379
380 func semawakeup(mp *m) {
381 if sem_post((*semt)(unsafe.Pointer(mp.waitsema))) != 0 {
382 throw("sem_post")
383 }
384 }
385
386
387 func closefd(fd int32) int32 {
388 return int32(sysvicall1(&libc_close, uintptr(fd)))
389 }
390
391
392 func exit(r int32) {
393 sysvicall1(&libc_exit, uintptr(r))
394 }
395
396
397 func getcontext(context *ucontext) {
398 sysvicall1(&libc_getcontext, uintptr(unsafe.Pointer(context)))
399 }
400
401
402 func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
403 sysvicall3(&libc_madvise, uintptr(addr), uintptr(n), uintptr(flags))
404 }
405
406
407 func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (unsafe.Pointer, int) {
408 p, err := doMmap(uintptr(addr), n, uintptr(prot), uintptr(flags), uintptr(fd), uintptr(off))
409 if p == ^uintptr(0) {
410 return nil, int(err)
411 }
412 return unsafe.Pointer(p), 0
413 }
414
415
416
417 func doMmap(addr, n, prot, flags, fd, off uintptr) (uintptr, uintptr) {
418 var libcall libcall
419 libcall.fn = uintptr(unsafe.Pointer(&libc_mmap))
420 libcall.n = 6
421 libcall.args = uintptr(noescape(unsafe.Pointer(&addr)))
422 asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
423 return libcall.r1, libcall.err
424 }
425
426
427 func munmap(addr unsafe.Pointer, n uintptr) {
428 sysvicall2(&libc_munmap, uintptr(addr), uintptr(n))
429 }
430
431 const (
432 _CLOCK_REALTIME = 3
433 _CLOCK_MONOTONIC = 4
434 )
435
436
437 func nanotime1() int64 {
438 var ts mts
439 sysvicall2(&libc_clock_gettime, _CLOCK_MONOTONIC, uintptr(unsafe.Pointer(&ts)))
440 return ts.tv_sec*1e9 + ts.tv_nsec
441 }
442
443
444 func open(path *byte, mode, perm int32) int32 {
445 return int32(sysvicall3(&libc_open, uintptr(unsafe.Pointer(path)), uintptr(mode), uintptr(perm)))
446 }
447
448 func pthread_attr_destroy(attr *pthreadattr) int32 {
449 return int32(sysvicall1(&libc_pthread_attr_destroy, uintptr(unsafe.Pointer(attr))))
450 }
451
452 func pthread_attr_getstack(attr *pthreadattr, addr unsafe.Pointer, size *uint64) int32 {
453 return int32(sysvicall3(&libc_pthread_attr_getstack, uintptr(unsafe.Pointer(attr)), uintptr(addr), uintptr(unsafe.Pointer(size))))
454 }
455
456 func pthread_attr_init(attr *pthreadattr) int32 {
457 return int32(sysvicall1(&libc_pthread_attr_init, uintptr(unsafe.Pointer(attr))))
458 }
459
460 func pthread_attr_setdetachstate(attr *pthreadattr, state int32) int32 {
461 return int32(sysvicall2(&libc_pthread_attr_setdetachstate, uintptr(unsafe.Pointer(attr)), uintptr(state)))
462 }
463
464 func pthread_attr_setstack(attr *pthreadattr, addr uintptr, size uint64) int32 {
465 return int32(sysvicall3(&libc_pthread_attr_setstack, uintptr(unsafe.Pointer(attr)), uintptr(addr), uintptr(size)))
466 }
467
468 func pthread_create(thread *pthread, attr *pthreadattr, fn uintptr, arg unsafe.Pointer) int32 {
469 return int32(sysvicall4(&libc_pthread_create, uintptr(unsafe.Pointer(thread)), uintptr(unsafe.Pointer(attr)), uintptr(fn), uintptr(arg)))
470 }
471
472 func pthread_self() pthread {
473 return pthread(sysvicall0(&libc_pthread_self))
474 }
475
476 func signalM(mp *m, sig int) {
477 sysvicall2(&libc_pthread_kill, uintptr(pthread(mp.procid)), uintptr(sig))
478 }
479
480
481
482 func raise(sig uint32) {
483 sysvicall1(&libc_raise, uintptr(sig))
484 }
485
486 func raiseproc(sig uint32) {
487 pid := sysvicall0(&libc_getpid)
488 sysvicall2(&libc_kill, pid, uintptr(sig))
489 }
490
491
492 func read(fd int32, buf unsafe.Pointer, nbyte int32) int32 {
493 r1, err := sysvicall3Err(&libc_read, uintptr(fd), uintptr(buf), uintptr(nbyte))
494 if c := int32(r1); c >= 0 {
495 return c
496 }
497 return -int32(err)
498 }
499
500
501 func sem_init(sem *semt, pshared int32, value uint32) int32 {
502 return int32(sysvicall3(&libc_sem_init, uintptr(unsafe.Pointer(sem)), uintptr(pshared), uintptr(value)))
503 }
504
505
506 func sem_post(sem *semt) int32 {
507 return int32(sysvicall1(&libc_sem_post, uintptr(unsafe.Pointer(sem))))
508 }
509
510
511 func sem_reltimedwait_np(sem *semt, timeout *timespec) int32 {
512 return int32(sysvicall2(&libc_sem_reltimedwait_np, uintptr(unsafe.Pointer(sem)), uintptr(unsafe.Pointer(timeout))))
513 }
514
515
516 func sem_wait(sem *semt) int32 {
517 return int32(sysvicall1(&libc_sem_wait, uintptr(unsafe.Pointer(sem))))
518 }
519
520 func setitimer(which int32, value *itimerval, ovalue *itimerval) {
521 sysvicall3(&libc_setitimer, uintptr(which), uintptr(unsafe.Pointer(value)), uintptr(unsafe.Pointer(ovalue)))
522 }
523
524
525
526 func sigaction(sig uint32, act *sigactiont, oact *sigactiont) {
527 sysvicall3(&libc_sigaction, uintptr(sig), uintptr(unsafe.Pointer(act)), uintptr(unsafe.Pointer(oact)))
528 }
529
530
531
532 func sigaltstack(ss *stackt, oss *stackt) {
533 sysvicall2(&libc_sigaltstack, uintptr(unsafe.Pointer(ss)), uintptr(unsafe.Pointer(oss)))
534 }
535
536
537
538 func sigprocmask(how int32, set *sigset, oset *sigset) {
539 sysvicall3(&libc_sigprocmask, uintptr(how), uintptr(unsafe.Pointer(set)), uintptr(unsafe.Pointer(oset)))
540 }
541
542 func sysconf(name int32) int64 {
543 return int64(sysvicall1(&libc_sysconf, uintptr(name)))
544 }
545
546 func usleep1(usec uint32)
547
548
549 func usleep_no_g(µs uint32) {
550 usleep1(µs)
551 }
552
553
554 func usleep(µs uint32) {
555 usleep1(µs)
556 }
557
558 func walltime() (sec int64, nsec int32) {
559 var ts mts
560 sysvicall2(&libc_clock_gettime, _CLOCK_REALTIME, uintptr(unsafe.Pointer(&ts)))
561 return ts.tv_sec, int32(ts.tv_nsec)
562 }
563
564
565 func write1(fd uintptr, buf unsafe.Pointer, nbyte int32) int32 {
566 r1, err := sysvicall3Err(&libc_write, fd, uintptr(buf), uintptr(nbyte))
567 if c := int32(r1); c >= 0 {
568 return c
569 }
570 return -int32(err)
571 }
572
573
574 func pipe2(flags int32) (r, w int32, errno int32) {
575 var p [2]int32
576 _, e := sysvicall2Err(&libc_pipe2, uintptr(noescape(unsafe.Pointer(&p))), uintptr(flags))
577 return p[0], p[1], int32(e)
578 }
579
580
581 func fcntl(fd, cmd, arg int32) (ret int32, errno int32) {
582 r1, err := sysvicall3Err(&libc_fcntl, uintptr(fd), uintptr(cmd), uintptr(arg))
583 return int32(r1), int32(err)
584 }
585
586 func osyield1()
587
588
589 func osyield_no_g() {
590 osyield1()
591 }
592
593
594 func osyield() {
595 sysvicall0(&libc_sched_yield)
596 }
597
598
599 var executablePath string
600
601 func sysargs(argc int32, argv **byte) {
602 n := argc + 1
603
604
605 for argv_index(argv, n) != nil {
606 n++
607 }
608
609
610 n++
611
612
613 auxvp := (*[1 << 28]uintptr)(add(unsafe.Pointer(argv), uintptr(n)*goarch.PtrSize))
614 pairs := sysauxv(auxvp[:])
615 auxv = auxvp[: pairs*2 : pairs*2]
616 }
617
618 const (
619 _AT_NULL = 0
620 _AT_PAGESZ = 6
621 _AT_SUN_EXECNAME = 2014
622 )
623
624 func sysauxv(auxv []uintptr) (pairs int) {
625 var i int
626 for i = 0; auxv[i] != _AT_NULL; i += 2 {
627 tag, val := auxv[i], auxv[i+1]
628 switch tag {
629 case _AT_PAGESZ:
630 physPageSize = val
631 case _AT_SUN_EXECNAME:
632 executablePath = gostringnocopy((*byte)(unsafe.Pointer(val)))
633 }
634 }
635 return i / 2
636 }
637
638
639
640 const sigPerThreadSyscall = 1 << 31
641
642
643 func runPerThreadSyscall() {
644 throw("runPerThreadSyscall only valid on linux")
645 }
646
View as plain text