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