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