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