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