github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/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 "unsafe" 8 9 //go:cgo_export_dynamic runtime.end _end 10 //go:cgo_export_dynamic runtime.etext _etext 11 //go:cgo_export_dynamic runtime.edata _edata 12 13 //go:cgo_import_dynamic libc____errno ___errno "libc.so" 14 //go:cgo_import_dynamic libc_clock_gettime clock_gettime "libc.so" 15 //go:cgo_import_dynamic libc_close close "libc.so" 16 //go:cgo_import_dynamic libc_exit exit "libc.so" 17 //go:cgo_import_dynamic libc_fstat fstat "libc.so" 18 //go:cgo_import_dynamic libc_getcontext getcontext "libc.so" 19 //go:cgo_import_dynamic libc_getrlimit getrlimit "libc.so" 20 //go:cgo_import_dynamic libc_kill kill "libc.so" 21 //go:cgo_import_dynamic libc_madvise madvise "libc.so" 22 //go:cgo_import_dynamic libc_malloc malloc "libc.so" 23 //go:cgo_import_dynamic libc_mmap mmap "libc.so" 24 //go:cgo_import_dynamic libc_munmap munmap "libc.so" 25 //go:cgo_import_dynamic libc_open open "libc.so" 26 //go:cgo_import_dynamic libc_pthread_attr_destroy pthread_attr_destroy "libc.so" 27 //go:cgo_import_dynamic libc_pthread_attr_getstack pthread_attr_getstack "libc.so" 28 //go:cgo_import_dynamic libc_pthread_attr_init pthread_attr_init "libc.so" 29 //go:cgo_import_dynamic libc_pthread_attr_setdetachstate pthread_attr_setdetachstate "libc.so" 30 //go:cgo_import_dynamic libc_pthread_attr_setstack pthread_attr_setstack "libc.so" 31 //go:cgo_import_dynamic libc_pthread_create pthread_create "libc.so" 32 //go:cgo_import_dynamic libc_raise raise "libc.so" 33 //go:cgo_import_dynamic libc_read read "libc.so" 34 //go:cgo_import_dynamic libc_select select "libc.so" 35 //go:cgo_import_dynamic libc_sched_yield sched_yield "libc.so" 36 //go:cgo_import_dynamic libc_sem_init sem_init "libc.so" 37 //go:cgo_import_dynamic libc_sem_post sem_post "libc.so" 38 //go:cgo_import_dynamic libc_sem_reltimedwait_np sem_reltimedwait_np "libc.so" 39 //go:cgo_import_dynamic libc_sem_wait sem_wait "libc.so" 40 //go:cgo_import_dynamic libc_setitimer setitimer "libc.so" 41 //go:cgo_import_dynamic libc_sigaction sigaction "libc.so" 42 //go:cgo_import_dynamic libc_sigaltstack sigaltstack "libc.so" 43 //go:cgo_import_dynamic libc_sigprocmask sigprocmask "libc.so" 44 //go:cgo_import_dynamic libc_sysconf sysconf "libc.so" 45 //go:cgo_import_dynamic libc_usleep usleep "libc.so" 46 //go:cgo_import_dynamic libc_write write "libc.so" 47 48 //go:linkname libc____errno libc____errno 49 //go:linkname libc_clock_gettime libc_clock_gettime 50 //go:linkname libc_close libc_close 51 //go:linkname libc_exit libc_exit 52 //go:linkname libc_fstat libc_fstat 53 //go:linkname libc_getcontext libc_getcontext 54 //go:linkname libc_getrlimit libc_getrlimit 55 //go:linkname libc_kill libc_kill 56 //go:linkname libc_madvise libc_madvise 57 //go:linkname libc_malloc libc_malloc 58 //go:linkname libc_mmap libc_mmap 59 //go:linkname libc_munmap libc_munmap 60 //go:linkname libc_open libc_open 61 //go:linkname libc_pthread_attr_destroy libc_pthread_attr_destroy 62 //go:linkname libc_pthread_attr_getstack libc_pthread_attr_getstack 63 //go:linkname libc_pthread_attr_init libc_pthread_attr_init 64 //go:linkname libc_pthread_attr_setdetachstate libc_pthread_attr_setdetachstate 65 //go:linkname libc_pthread_attr_setstack libc_pthread_attr_setstack 66 //go:linkname libc_pthread_create libc_pthread_create 67 //go:linkname libc_raise libc_raise 68 //go:linkname libc_read libc_read 69 //go:linkname libc_select libc_select 70 //go:linkname libc_sched_yield libc_sched_yield 71 //go:linkname libc_sem_init libc_sem_init 72 //go:linkname libc_sem_post libc_sem_post 73 //go:linkname libc_sem_reltimedwait_np libc_sem_reltimedwait_np 74 //go:linkname libc_sem_wait libc_sem_wait 75 //go:linkname libc_setitimer libc_setitimer 76 //go:linkname libc_sigaction libc_sigaction 77 //go:linkname libc_sigaltstack libc_sigaltstack 78 //go:linkname libc_sigprocmask libc_sigprocmask 79 //go:linkname libc_sysconf libc_sysconf 80 //go:linkname libc_usleep libc_usleep 81 //go:linkname libc_write libc_write 82 83 var ( 84 libc____errno, 85 libc_clock_gettime, 86 libc_close, 87 libc_exit, 88 libc_fstat, 89 libc_getcontext, 90 libc_getrlimit, 91 libc_kill, 92 libc_madvise, 93 libc_malloc, 94 libc_mmap, 95 libc_munmap, 96 libc_open, 97 libc_pthread_attr_destroy, 98 libc_pthread_attr_getstack, 99 libc_pthread_attr_init, 100 libc_pthread_attr_setdetachstate, 101 libc_pthread_attr_setstack, 102 libc_pthread_create, 103 libc_raise, 104 libc_read, 105 libc_sched_yield, 106 libc_select, 107 libc_sem_init, 108 libc_sem_post, 109 libc_sem_reltimedwait_np, 110 libc_sem_wait, 111 libc_setitimer, 112 libc_sigaction, 113 libc_sigaltstack, 114 libc_sigprocmask, 115 libc_sysconf, 116 libc_usleep, 117 libc_write libcFunc 118 ) 119 120 var sigset_all = sigset{[4]uint32{^uint32(0), ^uint32(0), ^uint32(0), ^uint32(0)}} 121 122 func getncpu() int32 { 123 n := int32(sysconf(__SC_NPROCESSORS_ONLN)) 124 if n < 1 { 125 return 1 126 } 127 return n 128 } 129 130 func getPageSize() uintptr { 131 n := int32(sysconf(__SC_PAGESIZE)) 132 if n <= 0 { 133 return 0 134 } 135 return uintptr(n) 136 } 137 138 func osinit() { 139 ncpu = getncpu() 140 physPageSize = getPageSize() 141 } 142 143 func tstart_sysvicall() 144 145 // May run with m.p==nil, so write barriers are not allowed. 146 //go:nowritebarrier 147 func newosproc(mp *m, _ unsafe.Pointer) { 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 if pthread_attr_setstack(&attr, 0, 0x200000) != 0 { 160 throw("pthread_attr_setstack") 161 } 162 if pthread_attr_getstack(&attr, unsafe.Pointer(&mp.g0.stack.hi), &size) != 0 { 163 throw("pthread_attr_getstack") 164 } 165 mp.g0.stack.lo = mp.g0.stack.hi - uintptr(size) 166 if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 { 167 throw("pthread_attr_setdetachstate") 168 } 169 170 // Disable signals during create, so that the new thread starts 171 // with signals disabled. It will enable them in minit. 172 sigprocmask(_SIG_SETMASK, &sigset_all, &oset) 173 ret = pthread_create(&tid, &attr, funcPC(tstart_sysvicall), unsafe.Pointer(mp)) 174 sigprocmask(_SIG_SETMASK, &oset, nil) 175 if ret != 0 { 176 print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", ret, ")\n") 177 if ret == -_EAGAIN { 178 println("runtime: may need to increase max user processes (ulimit -u)") 179 } 180 throw("newosproc") 181 } 182 } 183 184 var urandom_dev = []byte("/dev/urandom\x00") 185 186 //go:nosplit 187 func getRandomData(r []byte) { 188 fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0) 189 n := read(fd, unsafe.Pointer(&r[0]), int32(len(r))) 190 closefd(fd) 191 extendRandom(r, int(n)) 192 } 193 194 func goenvs() { 195 goenvs_unix() 196 } 197 198 // Called to initialize a new m (including the bootstrap m). 199 // Called on the parent thread (main thread in case of bootstrap), can allocate memory. 200 func mpreinit(mp *m) { 201 mp.gsignal = malg(32 * 1024) 202 mp.gsignal.m = mp 203 } 204 205 func miniterrno() 206 207 //go:nosplit 208 func msigsave(mp *m) { 209 sigprocmask(_SIG_SETMASK, nil, &mp.sigmask) 210 } 211 212 //go:nosplit 213 func msigrestore(sigmask sigset) { 214 sigprocmask(_SIG_SETMASK, &sigmask, nil) 215 } 216 217 //go:nosplit 218 func sigblock() { 219 sigprocmask(_SIG_SETMASK, &sigset_all, nil) 220 } 221 222 // Called to initialize a new m (including the bootstrap m). 223 // Called on the new thread, cannot allocate memory. 224 func minit() { 225 _g_ := getg() 226 asmcgocall(unsafe.Pointer(funcPC(miniterrno)), unsafe.Pointer(&libc____errno)) 227 // Initialize signal handling 228 var st sigaltstackt 229 sigaltstack(nil, &st) 230 if st.ss_flags&_SS_DISABLE != 0 { 231 signalstack(&_g_.m.gsignal.stack) 232 _g_.m.newSigstack = true 233 } else { 234 // Use existing signal stack. 235 stsp := uintptr(unsafe.Pointer(st.ss_sp)) 236 _g_.m.gsignal.stack.lo = stsp 237 _g_.m.gsignal.stack.hi = stsp + uintptr(st.ss_size) 238 _g_.m.gsignal.stackguard0 = stsp + _StackGuard 239 _g_.m.gsignal.stackguard1 = stsp + _StackGuard 240 _g_.m.gsignal.stackAlloc = uintptr(st.ss_size) 241 _g_.m.newSigstack = false 242 } 243 244 // restore signal mask from m.sigmask and unblock essential signals 245 nmask := _g_.m.sigmask 246 for i := range sigtable { 247 if sigtable[i].flags&_SigUnblock != 0 { 248 nmask.__sigbits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31) 249 } 250 } 251 sigprocmask(_SIG_SETMASK, &nmask, nil) 252 } 253 254 // Called from dropm to undo the effect of an minit. 255 func unminit() { 256 if getg().m.newSigstack { 257 signalstack(nil) 258 } 259 } 260 261 func memlimit() uintptr { 262 /* 263 TODO: Convert to Go when something actually uses the result. 264 Rlimit rl; 265 extern byte runtime·text[], runtime·end[]; 266 uintptr used; 267 268 if(runtime·getrlimit(RLIMIT_AS, &rl) != 0) 269 return 0; 270 if(rl.rlim_cur >= 0x7fffffff) 271 return 0; 272 273 // Estimate our VM footprint excluding the heap. 274 // Not an exact science: use size of binary plus 275 // some room for thread stacks. 276 used = runtime·end - runtime·text + (64<<20); 277 if(used >= rl.rlim_cur) 278 return 0; 279 280 // If there's not at least 16 MB left, we're probably 281 // not going to be able to do much. Treat as no limit. 282 rl.rlim_cur -= used; 283 if(rl.rlim_cur < (16<<20)) 284 return 0; 285 286 return rl.rlim_cur - used; 287 */ 288 289 return 0 290 } 291 292 func sigtramp() 293 294 //go:nosplit 295 //go:nowritebarrierrec 296 func setsig(i int32, fn uintptr, restart bool) { 297 var sa sigactiont 298 299 sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK 300 if restart { 301 sa.sa_flags |= _SA_RESTART 302 } 303 sa.sa_mask = sigset_all 304 if fn == funcPC(sighandler) { 305 fn = funcPC(sigtramp) 306 } 307 *((*uintptr)(unsafe.Pointer(&sa._funcptr))) = fn 308 sigaction(i, &sa, nil) 309 } 310 311 //go:nosplit 312 //go:nowritebarrierrec 313 func setsigstack(i int32) { 314 var sa sigactiont 315 sigaction(i, nil, &sa) 316 handler := *((*uintptr)(unsafe.Pointer(&sa._funcptr))) 317 if handler == 0 || handler == _SIG_DFL || handler == _SIG_IGN || sa.sa_flags&_SA_ONSTACK != 0 { 318 return 319 } 320 sa.sa_flags |= _SA_ONSTACK 321 sigaction(i, &sa, nil) 322 } 323 324 //go:nosplit 325 //go:nowritebarrierrec 326 func getsig(i int32) uintptr { 327 var sa sigactiont 328 sigaction(i, nil, &sa) 329 if *((*uintptr)(unsafe.Pointer(&sa._funcptr))) == funcPC(sigtramp) { 330 return funcPC(sighandler) 331 } 332 return *((*uintptr)(unsafe.Pointer(&sa._funcptr))) 333 } 334 335 //go:nosplit 336 func signalstack(s *stack) { 337 var st sigaltstackt 338 if s == nil { 339 st.ss_flags = _SS_DISABLE 340 } else { 341 st.ss_sp = (*byte)(unsafe.Pointer(s.lo)) 342 st.ss_size = uint64(s.hi - s.lo) 343 st.ss_flags = 0 344 } 345 sigaltstack(&st, nil) 346 } 347 348 //go:nosplit 349 //go:nowritebarrierrec 350 func updatesigmask(m sigmask) { 351 var mask sigset 352 copy(mask.__sigbits[:], m[:]) 353 sigprocmask(_SIG_SETMASK, &mask, nil) 354 } 355 356 func unblocksig(sig int32) { 357 var mask sigset 358 mask.__sigbits[(sig-1)/32] |= 1 << ((uint32(sig) - 1) & 31) 359 sigprocmask(_SIG_UNBLOCK, &mask, nil) 360 } 361 362 //go:nosplit 363 func semacreate(mp *m) { 364 if mp.waitsema != 0 { 365 return 366 } 367 368 var sem *semt 369 _g_ := getg() 370 371 // Call libc's malloc rather than malloc. This will 372 // allocate space on the C heap. We can't call malloc 373 // here because it could cause a deadlock. 374 _g_.m.libcall.fn = uintptr(unsafe.Pointer(&libc_malloc)) 375 _g_.m.libcall.n = 1 376 memclr(unsafe.Pointer(&_g_.m.scratch), uintptr(len(_g_.m.scratch.v))) 377 _g_.m.scratch.v[0] = unsafe.Sizeof(*sem) 378 _g_.m.libcall.args = uintptr(unsafe.Pointer(&_g_.m.scratch)) 379 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&_g_.m.libcall)) 380 sem = (*semt)(unsafe.Pointer(_g_.m.libcall.r1)) 381 if sem_init(sem, 0, 0) != 0 { 382 throw("sem_init") 383 } 384 mp.waitsema = uintptr(unsafe.Pointer(sem)) 385 } 386 387 //go:nosplit 388 func semasleep(ns int64) int32 { 389 _m_ := getg().m 390 if ns >= 0 { 391 _m_.ts.tv_sec = ns / 1000000000 392 _m_.ts.tv_nsec = ns % 1000000000 393 394 _m_.libcall.fn = uintptr(unsafe.Pointer(&libc_sem_reltimedwait_np)) 395 _m_.libcall.n = 2 396 memclr(unsafe.Pointer(&_m_.scratch), uintptr(len(_m_.scratch.v))) 397 _m_.scratch.v[0] = _m_.waitsema 398 _m_.scratch.v[1] = uintptr(unsafe.Pointer(&_m_.ts)) 399 _m_.libcall.args = uintptr(unsafe.Pointer(&_m_.scratch)) 400 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&_m_.libcall)) 401 if *_m_.perrno != 0 { 402 if *_m_.perrno == _ETIMEDOUT || *_m_.perrno == _EAGAIN || *_m_.perrno == _EINTR { 403 return -1 404 } 405 throw("sem_reltimedwait_np") 406 } 407 return 0 408 } 409 for { 410 _m_.libcall.fn = uintptr(unsafe.Pointer(&libc_sem_wait)) 411 _m_.libcall.n = 1 412 memclr(unsafe.Pointer(&_m_.scratch), uintptr(len(_m_.scratch.v))) 413 _m_.scratch.v[0] = _m_.waitsema 414 _m_.libcall.args = uintptr(unsafe.Pointer(&_m_.scratch)) 415 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&_m_.libcall)) 416 if _m_.libcall.r1 == 0 { 417 break 418 } 419 if *_m_.perrno == _EINTR { 420 continue 421 } 422 throw("sem_wait") 423 } 424 return 0 425 } 426 427 //go:nosplit 428 func semawakeup(mp *m) { 429 if sem_post((*semt)(unsafe.Pointer(mp.waitsema))) != 0 { 430 throw("sem_post") 431 } 432 } 433 434 //go:nosplit 435 func closefd(fd int32) int32 { 436 return int32(sysvicall1(&libc_close, uintptr(fd))) 437 } 438 439 //go:nosplit 440 func exit(r int32) { 441 sysvicall1(&libc_exit, uintptr(r)) 442 } 443 444 //go:nosplit 445 func getcontext(context *ucontext) /* int32 */ { 446 sysvicall1(&libc_getcontext, uintptr(unsafe.Pointer(context))) 447 } 448 449 //go:nosplit 450 func madvise(addr unsafe.Pointer, n uintptr, flags int32) { 451 sysvicall3(&libc_madvise, uintptr(addr), uintptr(n), uintptr(flags)) 452 } 453 454 //go:nosplit 455 func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer { 456 p, err := doMmap(uintptr(addr), n, uintptr(prot), uintptr(flags), uintptr(fd), uintptr(off)) 457 if p == ^uintptr(0) { 458 return unsafe.Pointer(err) 459 } 460 return unsafe.Pointer(p) 461 } 462 463 //go:nosplit 464 func doMmap(addr, n, prot, flags, fd, off uintptr) (uintptr, uintptr) { 465 var libcall libcall 466 libcall.fn = uintptr(unsafe.Pointer(&libc_mmap)) 467 libcall.n = 6 468 libcall.args = uintptr(noescape(unsafe.Pointer(&addr))) 469 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&libcall)) 470 return libcall.r1, libcall.err 471 } 472 473 //go:nosplit 474 func munmap(addr unsafe.Pointer, n uintptr) { 475 sysvicall2(&libc_munmap, uintptr(addr), uintptr(n)) 476 } 477 478 func nanotime1() 479 480 //go:nosplit 481 func nanotime() int64 { 482 return int64(sysvicall0((*libcFunc)(unsafe.Pointer(funcPC(nanotime1))))) 483 } 484 485 //go:nosplit 486 func open(path *byte, mode, perm int32) int32 { 487 return int32(sysvicall3(&libc_open, uintptr(unsafe.Pointer(path)), uintptr(mode), uintptr(perm))) 488 } 489 490 func pthread_attr_destroy(attr *pthreadattr) int32 { 491 return int32(sysvicall1(&libc_pthread_attr_destroy, uintptr(unsafe.Pointer(attr)))) 492 } 493 494 func pthread_attr_getstack(attr *pthreadattr, addr unsafe.Pointer, size *uint64) int32 { 495 return int32(sysvicall3(&libc_pthread_attr_getstack, uintptr(unsafe.Pointer(attr)), uintptr(addr), uintptr(unsafe.Pointer(size)))) 496 } 497 498 func pthread_attr_init(attr *pthreadattr) int32 { 499 return int32(sysvicall1(&libc_pthread_attr_init, uintptr(unsafe.Pointer(attr)))) 500 } 501 502 func pthread_attr_setdetachstate(attr *pthreadattr, state int32) int32 { 503 return int32(sysvicall2(&libc_pthread_attr_setdetachstate, uintptr(unsafe.Pointer(attr)), uintptr(state))) 504 } 505 506 func pthread_attr_setstack(attr *pthreadattr, addr uintptr, size uint64) int32 { 507 return int32(sysvicall3(&libc_pthread_attr_setstack, uintptr(unsafe.Pointer(attr)), uintptr(addr), uintptr(size))) 508 } 509 510 func pthread_create(thread *pthread, attr *pthreadattr, fn uintptr, arg unsafe.Pointer) int32 { 511 return int32(sysvicall4(&libc_pthread_create, uintptr(unsafe.Pointer(thread)), uintptr(unsafe.Pointer(attr)), uintptr(fn), uintptr(arg))) 512 } 513 514 //go:nosplit 515 //go:nowritebarrierrec 516 func raise(sig int32) /* int32 */ { 517 sysvicall1(&libc_raise, uintptr(sig)) 518 } 519 520 func raiseproc(sig int32) /* int32 */ { 521 pid := sysvicall0(&libc_getpid) 522 sysvicall2(&libc_kill, pid, uintptr(sig)) 523 } 524 525 //go:nosplit 526 func read(fd int32, buf unsafe.Pointer, nbyte int32) int32 { 527 return int32(sysvicall3(&libc_read, uintptr(fd), uintptr(buf), uintptr(nbyte))) 528 } 529 530 //go:nosplit 531 func sem_init(sem *semt, pshared int32, value uint32) int32 { 532 return int32(sysvicall3(&libc_sem_init, uintptr(unsafe.Pointer(sem)), uintptr(pshared), uintptr(value))) 533 } 534 535 //go:nosplit 536 func sem_post(sem *semt) int32 { 537 return int32(sysvicall1(&libc_sem_post, uintptr(unsafe.Pointer(sem)))) 538 } 539 540 //go:nosplit 541 func sem_reltimedwait_np(sem *semt, timeout *timespec) int32 { 542 return int32(sysvicall2(&libc_sem_reltimedwait_np, uintptr(unsafe.Pointer(sem)), uintptr(unsafe.Pointer(timeout)))) 543 } 544 545 //go:nosplit 546 func sem_wait(sem *semt) int32 { 547 return int32(sysvicall1(&libc_sem_wait, uintptr(unsafe.Pointer(sem)))) 548 } 549 550 func setitimer(which int32, value *itimerval, ovalue *itimerval) /* int32 */ { 551 sysvicall3(&libc_setitimer, uintptr(which), uintptr(unsafe.Pointer(value)), uintptr(unsafe.Pointer(ovalue))) 552 } 553 554 //go:nosplit 555 //go:nowritebarrierrec 556 func sigaction(sig int32, act *sigactiont, oact *sigactiont) /* int32 */ { 557 sysvicall3(&libc_sigaction, uintptr(sig), uintptr(unsafe.Pointer(act)), uintptr(unsafe.Pointer(oact))) 558 } 559 560 //go:nosplit 561 //go:nowritebarrierrec 562 func sigaltstack(ss *sigaltstackt, oss *sigaltstackt) /* int32 */ { 563 sysvicall2(&libc_sigaltstack, uintptr(unsafe.Pointer(ss)), uintptr(unsafe.Pointer(oss))) 564 } 565 566 //go:nosplit 567 //go:nowritebarrierrec 568 func sigprocmask(how int32, set *sigset, oset *sigset) /* int32 */ { 569 sysvicall3(&libc_sigprocmask, uintptr(how), uintptr(unsafe.Pointer(set)), uintptr(unsafe.Pointer(oset))) 570 } 571 572 func sysconf(name int32) int64 { 573 return int64(sysvicall1(&libc_sysconf, uintptr(name))) 574 } 575 576 func usleep1(uint32) 577 578 //go:nosplit 579 func usleep(µs uint32) { 580 usleep1(µs) 581 } 582 583 //go:nosplit 584 func write(fd uintptr, buf unsafe.Pointer, nbyte int32) int32 { 585 return int32(sysvicall3(&libc_write, uintptr(fd), uintptr(buf), uintptr(nbyte))) 586 } 587 588 func osyield1() 589 590 //go:nosplit 591 func osyield() { 592 _g_ := getg() 593 594 // Check the validity of m because we might be called in cgo callback 595 // path early enough where there isn't a m available yet. 596 if _g_ != nil && _g_.m != nil { 597 sysvicall0(&libc_sched_yield) 598 return 599 } 600 osyield1() 601 } 602 603 //go:nosplit 604 func threaddump() { 605 g := getg() 606 print("threaddump: g=", g, ", g.m=", g.m, ", g.m.g0=", g.m.g0, ", g.m.gsignal=", g.m.gsignal, "\n") 607 print(" g.stack.hi=", hex(g.stack.hi), ", g.stack.lo", hex(g.stack.lo), ", g.stackguard0=", hex(g.stackguard0), ", g.stackguard1=", hex(g.stackguard1), "\n") 608 print(" callersp=", hex(getcallersp(unsafe.Pointer(&g))), "\n") 609 }