github.com/AESNooper/go/src@v0.0.0-20220218095104-b56a4ab1bbbb/runtime/os3_solaris.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package runtime 6 7 import ( 8 "internal/abi" 9 "internal/goarch" 10 "unsafe" 11 ) 12 13 //go:cgo_export_dynamic runtime.end _end 14 //go:cgo_export_dynamic runtime.etext _etext 15 //go:cgo_export_dynamic runtime.edata _edata 16 17 //go:cgo_import_dynamic libc____errno ___errno "libc.so" 18 //go:cgo_import_dynamic libc_clock_gettime clock_gettime "libc.so" 19 //go:cgo_import_dynamic libc_exit exit "libc.so" 20 //go:cgo_import_dynamic libc_getcontext getcontext "libc.so" 21 //go:cgo_import_dynamic libc_kill kill "libc.so" 22 //go:cgo_import_dynamic libc_madvise madvise "libc.so" 23 //go:cgo_import_dynamic libc_malloc malloc "libc.so" 24 //go:cgo_import_dynamic libc_mmap mmap "libc.so" 25 //go:cgo_import_dynamic libc_munmap munmap "libc.so" 26 //go:cgo_import_dynamic libc_open open "libc.so" 27 //go:cgo_import_dynamic libc_pthread_attr_destroy pthread_attr_destroy "libc.so" 28 //go:cgo_import_dynamic libc_pthread_attr_getstack pthread_attr_getstack "libc.so" 29 //go:cgo_import_dynamic libc_pthread_attr_init pthread_attr_init "libc.so" 30 //go:cgo_import_dynamic libc_pthread_attr_setdetachstate pthread_attr_setdetachstate "libc.so" 31 //go:cgo_import_dynamic libc_pthread_attr_setstack pthread_attr_setstack "libc.so" 32 //go:cgo_import_dynamic libc_pthread_create pthread_create "libc.so" 33 //go:cgo_import_dynamic libc_pthread_self pthread_self "libc.so" 34 //go:cgo_import_dynamic libc_pthread_kill pthread_kill "libc.so" 35 //go:cgo_import_dynamic libc_raise raise "libc.so" 36 //go:cgo_import_dynamic libc_read read "libc.so" 37 //go:cgo_import_dynamic libc_select select "libc.so" 38 //go:cgo_import_dynamic libc_sched_yield sched_yield "libc.so" 39 //go:cgo_import_dynamic libc_sem_init sem_init "libc.so" 40 //go:cgo_import_dynamic libc_sem_post sem_post "libc.so" 41 //go:cgo_import_dynamic libc_sem_reltimedwait_np sem_reltimedwait_np "libc.so" 42 //go:cgo_import_dynamic libc_sem_wait sem_wait "libc.so" 43 //go:cgo_import_dynamic libc_setitimer setitimer "libc.so" 44 //go:cgo_import_dynamic libc_sigaction sigaction "libc.so" 45 //go:cgo_import_dynamic libc_sigaltstack sigaltstack "libc.so" 46 //go:cgo_import_dynamic libc_sigprocmask sigprocmask "libc.so" 47 //go:cgo_import_dynamic libc_sysconf sysconf "libc.so" 48 //go:cgo_import_dynamic libc_usleep usleep "libc.so" 49 //go:cgo_import_dynamic libc_write write "libc.so" 50 //go:cgo_import_dynamic libc_pipe pipe "libc.so" 51 //go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so" 52 53 //go:linkname libc____errno libc____errno 54 //go:linkname libc_clock_gettime libc_clock_gettime 55 //go:linkname libc_exit libc_exit 56 //go:linkname libc_getcontext libc_getcontext 57 //go:linkname libc_kill libc_kill 58 //go:linkname libc_madvise libc_madvise 59 //go:linkname libc_malloc libc_malloc 60 //go:linkname libc_mmap libc_mmap 61 //go:linkname libc_munmap libc_munmap 62 //go:linkname libc_open libc_open 63 //go:linkname libc_pthread_attr_destroy libc_pthread_attr_destroy 64 //go:linkname libc_pthread_attr_getstack libc_pthread_attr_getstack 65 //go:linkname libc_pthread_attr_init libc_pthread_attr_init 66 //go:linkname libc_pthread_attr_setdetachstate libc_pthread_attr_setdetachstate 67 //go:linkname libc_pthread_attr_setstack libc_pthread_attr_setstack 68 //go:linkname libc_pthread_create libc_pthread_create 69 //go:linkname libc_pthread_self libc_pthread_self 70 //go:linkname libc_pthread_kill libc_pthread_kill 71 //go:linkname libc_raise libc_raise 72 //go:linkname libc_read libc_read 73 //go:linkname libc_select libc_select 74 //go:linkname libc_sched_yield libc_sched_yield 75 //go:linkname libc_sem_init libc_sem_init 76 //go:linkname libc_sem_post libc_sem_post 77 //go:linkname libc_sem_reltimedwait_np libc_sem_reltimedwait_np 78 //go:linkname libc_sem_wait libc_sem_wait 79 //go:linkname libc_setitimer libc_setitimer 80 //go:linkname libc_sigaction libc_sigaction 81 //go:linkname libc_sigaltstack libc_sigaltstack 82 //go:linkname libc_sigprocmask libc_sigprocmask 83 //go:linkname libc_sysconf libc_sysconf 84 //go:linkname libc_usleep libc_usleep 85 //go:linkname libc_write libc_write 86 //go:linkname libc_pipe libc_pipe 87 //go:linkname libc_pipe2 libc_pipe2 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 // May run with m.p==nil, so write barriers are not allowed. 147 //go:nowritebarrier 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 // Allocate a new 2MB stack. 161 if pthread_attr_setstack(&attr, 0, 0x200000) != 0 { 162 throw("pthread_attr_setstack") 163 } 164 // Read back the allocated stack. 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 // Disable signals during create, so that the new thread starts 174 // with signals disabled. It will enable them in minit. 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 // We should never reach exitThread on Solaris because we let 189 // libc clean up threads. 190 throw("exitThread") 191 } 192 193 var urandom_dev = []byte("/dev/urandom\x00") 194 195 //go:nosplit 196 func getRandomData(r []byte) { 197 fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 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 // Called to initialize a new m (including the bootstrap m). 208 // Called on the parent thread (main thread in case of bootstrap), can allocate memory. 209 func mpreinit(mp *m) { 210 mp.gsignal = malg(32 * 1024) 211 mp.gsignal.m = mp 212 } 213 214 func miniterrno() 215 216 // Called to initialize a new m (including the bootstrap m). 217 // Called on the new thread, cannot allocate memory. 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 // Called from dropm to undo the effect of an minit. 227 func unminit() { 228 unminitSignals() 229 } 230 231 // Called from exitm, but not from drop, to undo the effect of thread-owned 232 // resources in minit, semacreate, or elsewhere. Do not take locks after calling this. 233 func mdestroy(mp *m) { 234 } 235 236 func sigtramp() 237 238 //go:nosplit 239 //go:nowritebarrierrec 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) { // abi.FuncPCABIInternal(sighandler) matches the callers in signal_unix.go 246 fn = abi.FuncPCABI0(sigtramp) 247 } 248 *((*uintptr)(unsafe.Pointer(&sa._funcptr))) = fn 249 sigaction(i, &sa, nil) 250 } 251 252 //go:nosplit 253 //go:nowritebarrierrec 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 //go:nosplit 265 //go:nowritebarrierrec 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 // setSignaltstackSP sets the ss_sp field of a stackt. 273 //go:nosplit 274 func setSignalstackSP(s *stackt, sp uintptr) { 275 *(*uintptr)(unsafe.Pointer(&s.ss_sp)) = sp 276 } 277 278 //go:nosplit 279 //go:nowritebarrierrec 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 //go:nosplit 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 //go:nosplit 301 func validSIGPROF(mp *m, c *sigctxt) bool { 302 return true 303 } 304 305 //go:nosplit 306 func semacreate(mp *m) { 307 if mp.waitsema != 0 { 308 return 309 } 310 311 var sem *semt 312 _g_ := getg() 313 314 // Call libc's malloc rather than malloc. This will 315 // allocate space on the C heap. We can't call malloc 316 // here because it could cause a deadlock. 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 //go:nosplit 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 //go:nosplit 371 func semawakeup(mp *m) { 372 if sem_post((*semt)(unsafe.Pointer(mp.waitsema))) != 0 { 373 throw("sem_post") 374 } 375 } 376 377 //go:nosplit 378 func closefd(fd int32) int32 { 379 return int32(sysvicall1(&libc_close, uintptr(fd))) 380 } 381 382 //go:nosplit 383 func exit(r int32) { 384 sysvicall1(&libc_exit, uintptr(r)) 385 } 386 387 //go:nosplit 388 func getcontext(context *ucontext) /* int32 */ { 389 sysvicall1(&libc_getcontext, uintptr(unsafe.Pointer(context))) 390 } 391 392 //go:nosplit 393 func madvise(addr unsafe.Pointer, n uintptr, flags int32) { 394 sysvicall3(&libc_madvise, uintptr(addr), uintptr(n), uintptr(flags)) 395 } 396 397 //go:nosplit 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 //go:nosplit 407 //go:cgo_unsafe_args 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 //go:nosplit 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 //go:nosplit 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 //go:nosplit 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 //go:nosplit 472 //go:nowritebarrierrec 473 func raise(sig uint32) /* int32 */ { 474 sysvicall1(&libc_raise, uintptr(sig)) 475 } 476 477 func raiseproc(sig uint32) /* int32 */ { 478 pid := sysvicall0(&libc_getpid) 479 sysvicall2(&libc_kill, pid, uintptr(sig)) 480 } 481 482 //go:nosplit 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 //go:nosplit 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 //go:nosplit 497 func sem_post(sem *semt) int32 { 498 return int32(sysvicall1(&libc_sem_post, uintptr(unsafe.Pointer(sem)))) 499 } 500 501 //go:nosplit 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 //go:nosplit 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) /* int32 */ { 512 sysvicall3(&libc_setitimer, uintptr(which), uintptr(unsafe.Pointer(value)), uintptr(unsafe.Pointer(ovalue))) 513 } 514 515 //go:nosplit 516 //go:nowritebarrierrec 517 func sigaction(sig uint32, act *sigactiont, oact *sigactiont) /* int32 */ { 518 sysvicall3(&libc_sigaction, uintptr(sig), uintptr(unsafe.Pointer(act)), uintptr(unsafe.Pointer(oact))) 519 } 520 521 //go:nosplit 522 //go:nowritebarrierrec 523 func sigaltstack(ss *stackt, oss *stackt) /* int32 */ { 524 sysvicall2(&libc_sigaltstack, uintptr(unsafe.Pointer(ss)), uintptr(unsafe.Pointer(oss))) 525 } 526 527 //go:nosplit 528 //go:nowritebarrierrec 529 func sigprocmask(how int32, set *sigset, oset *sigset) /* int32 */ { 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 //go:nosplit 540 func usleep_no_g(µs uint32) { 541 usleep1(µs) 542 } 543 544 //go:nosplit 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 //go:nosplit 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 //go:nosplit 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 //go:nosplit 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 //go:nosplit 579 func closeonexec(fd int32) { 580 fcntl(fd, _F_SETFD, _FD_CLOEXEC) 581 } 582 583 //go:nosplit 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 //go:nosplit 592 func osyield_no_g() { 593 osyield1() 594 } 595 596 //go:nosplit 597 func osyield() { 598 sysvicall0(&libc_sched_yield) 599 } 600 601 //go:linkname executablePath os.executablePath 602 var executablePath string 603 604 func sysargs(argc int32, argv **byte) { 605 n := argc + 1 606 607 // skip over argv, envp to get to auxv 608 for argv_index(argv, n) != nil { 609 n++ 610 } 611 612 // skip NULL separator 613 n++ 614 615 // now argv+n is auxv 616 auxv := (*[1 << 28]uintptr)(add(unsafe.Pointer(argv), uintptr(n)*goarch.PtrSize)) 617 sysauxv(auxv[:]) 618 } 619 620 const ( 621 _AT_NULL = 0 // Terminates the vector 622 _AT_PAGESZ = 6 // Page size in bytes 623 _AT_SUN_EXECNAME = 2014 // exec() path name 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 }