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