github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/runtime/os2_aix.go (about) 1 // Copyright 2018 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 // This file contains main runtime AIX syscalls. 6 // Pollset syscalls are in netpoll_aix.go. 7 // The implementation is based on Solaris and Windows. 8 // Each syscall is made by calling its libc symbol using asmcgocall and asmsyscall6 9 // assembly functions. 10 11 package runtime 12 13 import ( 14 "unsafe" 15 ) 16 17 // Symbols imported for __start function. 18 19 //go:cgo_import_dynamic libc___n_pthreads __n_pthreads "libpthread.a/shr_xpg5_64.o" 20 //go:cgo_import_dynamic libc___mod_init __mod_init "libc.a/shr_64.o" 21 //go:linkname libc___n_pthreads libc___n_pthreads 22 //go:linkname libc___mod_init libc___mod_init 23 24 var ( 25 libc___n_pthreads, 26 libc___mod_init libFunc 27 ) 28 29 // Syscalls 30 31 //go:cgo_import_dynamic libc__Errno _Errno "libc.a/shr_64.o" 32 //go:cgo_import_dynamic libc_clock_gettime clock_gettime "libc.a/shr_64.o" 33 //go:cgo_import_dynamic libc_close close "libc.a/shr_64.o" 34 //go:cgo_import_dynamic libc_exit _exit "libc.a/shr_64.o" 35 //go:cgo_import_dynamic libc_getpid getpid "libc.a/shr_64.o" 36 //go:cgo_import_dynamic libc_getsystemcfg getsystemcfg "libc.a/shr_64.o" 37 //go:cgo_import_dynamic libc_kill kill "libc.a/shr_64.o" 38 //go:cgo_import_dynamic libc_madvise madvise "libc.a/shr_64.o" 39 //go:cgo_import_dynamic libc_malloc malloc "libc.a/shr_64.o" 40 //go:cgo_import_dynamic libc_mmap mmap "libc.a/shr_64.o" 41 //go:cgo_import_dynamic libc_mprotect mprotect "libc.a/shr_64.o" 42 //go:cgo_import_dynamic libc_munmap munmap "libc.a/shr_64.o" 43 //go:cgo_import_dynamic libc_open open "libc.a/shr_64.o" 44 //go:cgo_import_dynamic libc_pipe pipe "libc.a/shr_64.o" 45 //go:cgo_import_dynamic libc_raise raise "libc.a/shr_64.o" 46 //go:cgo_import_dynamic libc_read read "libc.a/shr_64.o" 47 //go:cgo_import_dynamic libc_sched_yield sched_yield "libc.a/shr_64.o" 48 //go:cgo_import_dynamic libc_sem_init sem_init "libc.a/shr_64.o" 49 //go:cgo_import_dynamic libc_sem_post sem_post "libc.a/shr_64.o" 50 //go:cgo_import_dynamic libc_sem_timedwait sem_timedwait "libc.a/shr_64.o" 51 //go:cgo_import_dynamic libc_sem_wait sem_wait "libc.a/shr_64.o" 52 //go:cgo_import_dynamic libc_setitimer setitimer "libc.a/shr_64.o" 53 //go:cgo_import_dynamic libc_sigaction sigaction "libc.a/shr_64.o" 54 //go:cgo_import_dynamic libc_sigaltstack sigaltstack "libc.a/shr_64.o" 55 //go:cgo_import_dynamic libc_sysconf sysconf "libc.a/shr_64.o" 56 //go:cgo_import_dynamic libc_usleep usleep "libc.a/shr_64.o" 57 //go:cgo_import_dynamic libc_write write "libc.a/shr_64.o" 58 59 //go:cgo_import_dynamic libpthread___pth_init __pth_init "libpthread.a/shr_xpg5_64.o" 60 //go:cgo_import_dynamic libpthread_attr_destroy pthread_attr_destroy "libpthread.a/shr_xpg5_64.o" 61 //go:cgo_import_dynamic libpthread_attr_init pthread_attr_init "libpthread.a/shr_xpg5_64.o" 62 //go:cgo_import_dynamic libpthread_attr_getstacksize pthread_attr_getstacksize "libpthread.a/shr_xpg5_64.o" 63 //go:cgo_import_dynamic libpthread_attr_setstacksize pthread_attr_setstacksize "libpthread.a/shr_xpg5_64.o" 64 //go:cgo_import_dynamic libpthread_attr_setdetachstate pthread_attr_setdetachstate "libpthread.a/shr_xpg5_64.o" 65 //go:cgo_import_dynamic libpthread_attr_setstackaddr pthread_attr_setstackaddr "libpthread.a/shr_xpg5_64.o" 66 //go:cgo_import_dynamic libpthread_create pthread_create "libpthread.a/shr_xpg5_64.o" 67 //go:cgo_import_dynamic libpthread_sigthreadmask sigthreadmask "libpthread.a/shr_xpg5_64.o" 68 //go:cgo_import_dynamic libpthread_self pthread_self "libpthread.a/shr_xpg5_64.o" 69 //go:cgo_import_dynamic libpthread_kill pthread_kill "libpthread.a/shr_xpg5_64.o" 70 71 //go:linkname libc__Errno libc__Errno 72 //go:linkname libc_clock_gettime libc_clock_gettime 73 //go:linkname libc_close libc_close 74 //go:linkname libc_exit libc_exit 75 //go:linkname libc_getpid libc_getpid 76 //go:linkname libc_getsystemcfg libc_getsystemcfg 77 //go:linkname libc_kill libc_kill 78 //go:linkname libc_madvise libc_madvise 79 //go:linkname libc_malloc libc_malloc 80 //go:linkname libc_mmap libc_mmap 81 //go:linkname libc_mprotect libc_mprotect 82 //go:linkname libc_munmap libc_munmap 83 //go:linkname libc_open libc_open 84 //go:linkname libc_pipe libc_pipe 85 //go:linkname libc_raise libc_raise 86 //go:linkname libc_read libc_read 87 //go:linkname libc_sched_yield libc_sched_yield 88 //go:linkname libc_sem_init libc_sem_init 89 //go:linkname libc_sem_post libc_sem_post 90 //go:linkname libc_sem_timedwait libc_sem_timedwait 91 //go:linkname libc_sem_wait libc_sem_wait 92 //go:linkname libc_setitimer libc_setitimer 93 //go:linkname libc_sigaction libc_sigaction 94 //go:linkname libc_sigaltstack libc_sigaltstack 95 //go:linkname libc_sysconf libc_sysconf 96 //go:linkname libc_usleep libc_usleep 97 //go:linkname libc_write libc_write 98 99 //go:linkname libpthread___pth_init libpthread___pth_init 100 //go:linkname libpthread_attr_destroy libpthread_attr_destroy 101 //go:linkname libpthread_attr_init libpthread_attr_init 102 //go:linkname libpthread_attr_getstacksize libpthread_attr_getstacksize 103 //go:linkname libpthread_attr_setstacksize libpthread_attr_setstacksize 104 //go:linkname libpthread_attr_setdetachstate libpthread_attr_setdetachstate 105 //go:linkname libpthread_attr_setstackaddr libpthread_attr_setstackaddr 106 //go:linkname libpthread_create libpthread_create 107 //go:linkname libpthread_sigthreadmask libpthread_sigthreadmask 108 //go:linkname libpthread_self libpthread_self 109 //go:linkname libpthread_kill libpthread_kill 110 111 var ( 112 //libc 113 libc__Errno, 114 libc_clock_gettime, 115 libc_close, 116 libc_exit, 117 libc_getpid, 118 libc_getsystemcfg, 119 libc_kill, 120 libc_madvise, 121 libc_malloc, 122 libc_mmap, 123 libc_mprotect, 124 libc_munmap, 125 libc_open, 126 libc_pipe, 127 libc_raise, 128 libc_read, 129 libc_sched_yield, 130 libc_sem_init, 131 libc_sem_post, 132 libc_sem_timedwait, 133 libc_sem_wait, 134 libc_setitimer, 135 libc_sigaction, 136 libc_sigaltstack, 137 libc_sysconf, 138 libc_usleep, 139 libc_write, 140 //libpthread 141 libpthread___pth_init, 142 libpthread_attr_destroy, 143 libpthread_attr_init, 144 libpthread_attr_getstacksize, 145 libpthread_attr_setstacksize, 146 libpthread_attr_setdetachstate, 147 libpthread_attr_setstackaddr, 148 libpthread_create, 149 libpthread_sigthreadmask, 150 libpthread_self, 151 libpthread_kill libFunc 152 ) 153 154 type libFunc uintptr 155 156 // asmsyscall6 calls the libc symbol using a C convention. 157 // It's defined in sys_aix_ppc64.go. 158 var asmsyscall6 libFunc 159 160 // syscallX functions must always be called with g != nil and m != nil, 161 // as it relies on g.m.libcall to pass arguments to asmcgocall. 162 // The few cases where syscalls haven't a g or a m must call their equivalent 163 // function in sys_aix_ppc64.s to handle them. 164 165 //go:nowritebarrier 166 //go:nosplit 167 func syscall0(fn *libFunc) (r, err uintptr) { 168 gp := getg() 169 mp := gp.m 170 resetLibcall := true 171 if mp.libcallsp == 0 { 172 mp.libcallg.set(gp) 173 mp.libcallpc = getcallerpc() 174 // sp must be the last, because once async cpu profiler finds 175 // all three values to be non-zero, it will use them 176 mp.libcallsp = getcallersp() 177 } else { 178 resetLibcall = false // See comment in sys_darwin.go:libcCall 179 } 180 181 c := libcall{ 182 fn: uintptr(unsafe.Pointer(fn)), 183 n: 0, 184 args: uintptr(unsafe.Pointer(&fn)), // it's unused but must be non-nil, otherwise crashes 185 } 186 187 asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(&c)) 188 189 if resetLibcall { 190 mp.libcallsp = 0 191 } 192 193 return c.r1, c.err 194 } 195 196 //go:nowritebarrier 197 //go:nosplit 198 func syscall1(fn *libFunc, a0 uintptr) (r, err uintptr) { 199 gp := getg() 200 mp := gp.m 201 resetLibcall := true 202 if mp.libcallsp == 0 { 203 mp.libcallg.set(gp) 204 mp.libcallpc = getcallerpc() 205 // sp must be the last, because once async cpu profiler finds 206 // all three values to be non-zero, it will use them 207 mp.libcallsp = getcallersp() 208 } else { 209 resetLibcall = false // See comment in sys_darwin.go:libcCall 210 } 211 212 c := libcall{ 213 fn: uintptr(unsafe.Pointer(fn)), 214 n: 1, 215 args: uintptr(unsafe.Pointer(&a0)), 216 } 217 218 asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(&c)) 219 220 if resetLibcall { 221 mp.libcallsp = 0 222 } 223 224 return c.r1, c.err 225 } 226 227 //go:nowritebarrier 228 //go:nosplit 229 //go:cgo_unsafe_args 230 func syscall2(fn *libFunc, a0, a1 uintptr) (r, err uintptr) { 231 gp := getg() 232 mp := gp.m 233 resetLibcall := true 234 if mp.libcallsp == 0 { 235 mp.libcallg.set(gp) 236 mp.libcallpc = getcallerpc() 237 // sp must be the last, because once async cpu profiler finds 238 // all three values to be non-zero, it will use them 239 mp.libcallsp = getcallersp() 240 } else { 241 resetLibcall = false // See comment in sys_darwin.go:libcCall 242 } 243 244 c := libcall{ 245 fn: uintptr(unsafe.Pointer(fn)), 246 n: 2, 247 args: uintptr(unsafe.Pointer(&a0)), 248 } 249 250 asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(&c)) 251 252 if resetLibcall { 253 mp.libcallsp = 0 254 } 255 256 return c.r1, c.err 257 } 258 259 //go:nowritebarrier 260 //go:nosplit 261 //go:cgo_unsafe_args 262 func syscall3(fn *libFunc, a0, a1, a2 uintptr) (r, err uintptr) { 263 gp := getg() 264 mp := gp.m 265 resetLibcall := true 266 if mp.libcallsp == 0 { 267 mp.libcallg.set(gp) 268 mp.libcallpc = getcallerpc() 269 // sp must be the last, because once async cpu profiler finds 270 // all three values to be non-zero, it will use them 271 mp.libcallsp = getcallersp() 272 } else { 273 resetLibcall = false // See comment in sys_darwin.go:libcCall 274 } 275 276 c := libcall{ 277 fn: uintptr(unsafe.Pointer(fn)), 278 n: 3, 279 args: uintptr(unsafe.Pointer(&a0)), 280 } 281 282 asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(&c)) 283 284 if resetLibcall { 285 mp.libcallsp = 0 286 } 287 288 return c.r1, c.err 289 } 290 291 //go:nowritebarrier 292 //go:nosplit 293 //go:cgo_unsafe_args 294 func syscall4(fn *libFunc, a0, a1, a2, a3 uintptr) (r, err uintptr) { 295 gp := getg() 296 mp := gp.m 297 resetLibcall := true 298 if mp.libcallsp == 0 { 299 mp.libcallg.set(gp) 300 mp.libcallpc = getcallerpc() 301 // sp must be the last, because once async cpu profiler finds 302 // all three values to be non-zero, it will use them 303 mp.libcallsp = getcallersp() 304 } else { 305 resetLibcall = false // See comment in sys_darwin.go:libcCall 306 } 307 308 c := libcall{ 309 fn: uintptr(unsafe.Pointer(fn)), 310 n: 4, 311 args: uintptr(unsafe.Pointer(&a0)), 312 } 313 314 asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(&c)) 315 316 if resetLibcall { 317 mp.libcallsp = 0 318 } 319 320 return c.r1, c.err 321 } 322 323 //go:nowritebarrier 324 //go:nosplit 325 //go:cgo_unsafe_args 326 func syscall5(fn *libFunc, a0, a1, a2, a3, a4 uintptr) (r, err uintptr) { 327 gp := getg() 328 mp := gp.m 329 resetLibcall := true 330 if mp.libcallsp == 0 { 331 mp.libcallg.set(gp) 332 mp.libcallpc = getcallerpc() 333 // sp must be the last, because once async cpu profiler finds 334 // all three values to be non-zero, it will use them 335 mp.libcallsp = getcallersp() 336 } else { 337 resetLibcall = false // See comment in sys_darwin.go:libcCall 338 } 339 340 c := libcall{ 341 fn: uintptr(unsafe.Pointer(fn)), 342 n: 5, 343 args: uintptr(unsafe.Pointer(&a0)), 344 } 345 346 asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(&c)) 347 348 if resetLibcall { 349 mp.libcallsp = 0 350 } 351 352 return c.r1, c.err 353 } 354 355 //go:nowritebarrier 356 //go:nosplit 357 //go:cgo_unsafe_args 358 func syscall6(fn *libFunc, a0, a1, a2, a3, a4, a5 uintptr) (r, err uintptr) { 359 gp := getg() 360 mp := gp.m 361 resetLibcall := true 362 if mp.libcallsp == 0 { 363 mp.libcallg.set(gp) 364 mp.libcallpc = getcallerpc() 365 // sp must be the last, because once async cpu profiler finds 366 // all three values to be non-zero, it will use them 367 mp.libcallsp = getcallersp() 368 } else { 369 resetLibcall = false // See comment in sys_darwin.go:libcCall 370 } 371 372 c := libcall{ 373 fn: uintptr(unsafe.Pointer(fn)), 374 n: 6, 375 args: uintptr(unsafe.Pointer(&a0)), 376 } 377 378 asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(&c)) 379 380 if resetLibcall { 381 mp.libcallsp = 0 382 } 383 384 return c.r1, c.err 385 } 386 387 func exit1(code int32) 388 389 //go:nosplit 390 func exit(code int32) { 391 gp := getg() 392 393 // Check the validity of g because without a g during 394 // newosproc0. 395 if gp != nil { 396 syscall1(&libc_exit, uintptr(code)) 397 return 398 } 399 exit1(code) 400 } 401 402 func write2(fd, p uintptr, n int32) int32 403 404 //go:nosplit 405 func write1(fd uintptr, p unsafe.Pointer, n int32) int32 { 406 gp := getg() 407 408 // Check the validity of g because without a g during 409 // newosproc0. 410 if gp != nil { 411 r, errno := syscall3(&libc_write, uintptr(fd), uintptr(p), uintptr(n)) 412 if int32(r) < 0 { 413 return -int32(errno) 414 } 415 return int32(r) 416 } 417 // Note that in this case we can't return a valid errno value. 418 return write2(fd, uintptr(p), n) 419 420 } 421 422 //go:nosplit 423 func read(fd int32, p unsafe.Pointer, n int32) int32 { 424 r, errno := syscall3(&libc_read, uintptr(fd), uintptr(p), uintptr(n)) 425 if int32(r) < 0 { 426 return -int32(errno) 427 } 428 return int32(r) 429 } 430 431 //go:nosplit 432 func open(name *byte, mode, perm int32) int32 { 433 r, _ := syscall3(&libc_open, uintptr(unsafe.Pointer(name)), uintptr(mode), uintptr(perm)) 434 return int32(r) 435 } 436 437 //go:nosplit 438 func closefd(fd int32) int32 { 439 r, _ := syscall1(&libc_close, uintptr(fd)) 440 return int32(r) 441 } 442 443 //go:nosplit 444 func pipe() (r, w int32, errno int32) { 445 var p [2]int32 446 _, err := syscall1(&libc_pipe, uintptr(noescape(unsafe.Pointer(&p[0])))) 447 return p[0], p[1], int32(err) 448 } 449 450 // mmap calls the mmap system call. 451 // We only pass the lower 32 bits of file offset to the 452 // assembly routine; the higher bits (if required), should be provided 453 // by the assembly routine as 0. 454 // The err result is an OS error code such as ENOMEM. 455 // 456 //go:nosplit 457 func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (unsafe.Pointer, int) { 458 r, err0 := syscall6(&libc_mmap, uintptr(addr), uintptr(n), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(off)) 459 if r == ^uintptr(0) { 460 return nil, int(err0) 461 } 462 return unsafe.Pointer(r), int(err0) 463 } 464 465 //go:nosplit 466 func mprotect(addr unsafe.Pointer, n uintptr, prot int32) (unsafe.Pointer, int) { 467 r, err0 := syscall3(&libc_mprotect, uintptr(addr), uintptr(n), uintptr(prot)) 468 if r == ^uintptr(0) { 469 return nil, int(err0) 470 } 471 return unsafe.Pointer(r), int(err0) 472 } 473 474 //go:nosplit 475 func munmap(addr unsafe.Pointer, n uintptr) { 476 r, err := syscall2(&libc_munmap, uintptr(addr), uintptr(n)) 477 if int32(r) == -1 { 478 println("syscall munmap failed: ", hex(err)) 479 throw("syscall munmap") 480 } 481 } 482 483 //go:nosplit 484 func madvise(addr unsafe.Pointer, n uintptr, flags int32) { 485 r, err := syscall3(&libc_madvise, uintptr(addr), uintptr(n), uintptr(flags)) 486 if int32(r) == -1 { 487 println("syscall madvise failed: ", hex(err)) 488 throw("syscall madvise") 489 } 490 } 491 492 func sigaction1(sig, new, old uintptr) 493 494 //go:nosplit 495 func sigaction(sig uintptr, new, old *sigactiont) { 496 gp := getg() 497 498 // Check the validity of g because without a g during 499 // runtime.libpreinit. 500 if gp != nil { 501 r, err := syscall3(&libc_sigaction, sig, uintptr(unsafe.Pointer(new)), uintptr(unsafe.Pointer(old))) 502 if int32(r) == -1 { 503 println("Sigaction failed for sig: ", sig, " with error:", hex(err)) 504 throw("syscall sigaction") 505 } 506 return 507 } 508 509 sigaction1(sig, uintptr(unsafe.Pointer(new)), uintptr(unsafe.Pointer(old))) 510 } 511 512 //go:nosplit 513 func sigaltstack(new, old *stackt) { 514 r, err := syscall2(&libc_sigaltstack, uintptr(unsafe.Pointer(new)), uintptr(unsafe.Pointer(old))) 515 if int32(r) == -1 { 516 println("syscall sigaltstack failed: ", hex(err)) 517 throw("syscall sigaltstack") 518 } 519 } 520 521 //go:nosplit 522 //go:linkname internal_cpu_getsystemcfg internal/cpu.getsystemcfg 523 func internal_cpu_getsystemcfg(label uint) uint { 524 r, _ := syscall1(&libc_getsystemcfg, uintptr(label)) 525 return uint(r) 526 } 527 528 func usleep1(us uint32) 529 530 //go:nosplit 531 func usleep_no_g(us uint32) { 532 usleep1(us) 533 } 534 535 //go:nosplit 536 func usleep(us uint32) { 537 r, err := syscall1(&libc_usleep, uintptr(us)) 538 if int32(r) == -1 { 539 println("syscall usleep failed: ", hex(err)) 540 throw("syscall usleep") 541 } 542 } 543 544 //go:nosplit 545 func clock_gettime(clockid int32, tp *timespec) int32 { 546 r, _ := syscall2(&libc_clock_gettime, uintptr(clockid), uintptr(unsafe.Pointer(tp))) 547 return int32(r) 548 } 549 550 //go:nosplit 551 func setitimer(mode int32, new, old *itimerval) { 552 r, err := syscall3(&libc_setitimer, uintptr(mode), uintptr(unsafe.Pointer(new)), uintptr(unsafe.Pointer(old))) 553 if int32(r) == -1 { 554 println("syscall setitimer failed: ", hex(err)) 555 throw("syscall setitimer") 556 } 557 } 558 559 //go:nosplit 560 func malloc(size uintptr) unsafe.Pointer { 561 r, _ := syscall1(&libc_malloc, size) 562 return unsafe.Pointer(r) 563 } 564 565 //go:nosplit 566 func sem_init(sem *semt, pshared int32, value uint32) int32 { 567 r, _ := syscall3(&libc_sem_init, uintptr(unsafe.Pointer(sem)), uintptr(pshared), uintptr(value)) 568 return int32(r) 569 } 570 571 //go:nosplit 572 func sem_wait(sem *semt) (int32, int32) { 573 r, err := syscall1(&libc_sem_wait, uintptr(unsafe.Pointer(sem))) 574 return int32(r), int32(err) 575 } 576 577 //go:nosplit 578 func sem_post(sem *semt) int32 { 579 r, _ := syscall1(&libc_sem_post, uintptr(unsafe.Pointer(sem))) 580 return int32(r) 581 } 582 583 //go:nosplit 584 func sem_timedwait(sem *semt, timeout *timespec) (int32, int32) { 585 r, err := syscall2(&libc_sem_timedwait, uintptr(unsafe.Pointer(sem)), uintptr(unsafe.Pointer(timeout))) 586 return int32(r), int32(err) 587 } 588 589 //go:nosplit 590 func raise(sig uint32) { 591 r, err := syscall1(&libc_raise, uintptr(sig)) 592 if int32(r) == -1 { 593 println("syscall raise failed: ", hex(err)) 594 throw("syscall raise") 595 } 596 } 597 598 //go:nosplit 599 func raiseproc(sig uint32) { 600 pid, err := syscall0(&libc_getpid) 601 if int32(pid) == -1 { 602 println("syscall getpid failed: ", hex(err)) 603 throw("syscall raiseproc") 604 } 605 606 syscall2(&libc_kill, pid, uintptr(sig)) 607 } 608 609 func osyield1() 610 611 //go:nosplit 612 func osyield_no_g() { 613 osyield1() 614 } 615 616 //go:nosplit 617 func osyield() { 618 r, err := syscall0(&libc_sched_yield) 619 if int32(r) == -1 { 620 println("syscall osyield failed: ", hex(err)) 621 throw("syscall osyield") 622 } 623 } 624 625 //go:nosplit 626 func sysconf(name int32) uintptr { 627 r, _ := syscall1(&libc_sysconf, uintptr(name)) 628 if int32(r) == -1 { 629 throw("syscall sysconf") 630 } 631 return r 632 633 } 634 635 // pthread functions returns its error code in the main return value 636 // Therefore, err returns by syscall means nothing and must not be used 637 638 //go:nosplit 639 func pthread_attr_destroy(attr *pthread_attr) int32 { 640 r, _ := syscall1(&libpthread_attr_destroy, uintptr(unsafe.Pointer(attr))) 641 return int32(r) 642 } 643 644 func pthread_attr_init1(attr uintptr) int32 645 646 //go:nosplit 647 func pthread_attr_init(attr *pthread_attr) int32 { 648 gp := getg() 649 650 // Check the validity of g because without a g during 651 // newosproc0. 652 if gp != nil { 653 r, _ := syscall1(&libpthread_attr_init, uintptr(unsafe.Pointer(attr))) 654 return int32(r) 655 } 656 657 return pthread_attr_init1(uintptr(unsafe.Pointer(attr))) 658 } 659 660 func pthread_attr_setdetachstate1(attr uintptr, state int32) int32 661 662 //go:nosplit 663 func pthread_attr_setdetachstate(attr *pthread_attr, state int32) int32 { 664 gp := getg() 665 666 // Check the validity of g because without a g during 667 // newosproc0. 668 if gp != nil { 669 r, _ := syscall2(&libpthread_attr_setdetachstate, uintptr(unsafe.Pointer(attr)), uintptr(state)) 670 return int32(r) 671 } 672 673 return pthread_attr_setdetachstate1(uintptr(unsafe.Pointer(attr)), state) 674 } 675 676 //go:nosplit 677 func pthread_attr_setstackaddr(attr *pthread_attr, stk unsafe.Pointer) int32 { 678 r, _ := syscall2(&libpthread_attr_setstackaddr, uintptr(unsafe.Pointer(attr)), uintptr(stk)) 679 return int32(r) 680 } 681 682 //go:nosplit 683 func pthread_attr_getstacksize(attr *pthread_attr, size *uint64) int32 { 684 r, _ := syscall2(&libpthread_attr_getstacksize, uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(size))) 685 return int32(r) 686 } 687 688 func pthread_attr_setstacksize1(attr uintptr, size uint64) int32 689 690 //go:nosplit 691 func pthread_attr_setstacksize(attr *pthread_attr, size uint64) int32 { 692 gp := getg() 693 694 // Check the validity of g because without a g during 695 // newosproc0. 696 if gp != nil { 697 r, _ := syscall2(&libpthread_attr_setstacksize, uintptr(unsafe.Pointer(attr)), uintptr(size)) 698 return int32(r) 699 } 700 701 return pthread_attr_setstacksize1(uintptr(unsafe.Pointer(attr)), size) 702 } 703 704 func pthread_create1(tid, attr, fn, arg uintptr) int32 705 706 //go:nosplit 707 func pthread_create(tid *pthread, attr *pthread_attr, fn *funcDescriptor, arg unsafe.Pointer) int32 { 708 gp := getg() 709 710 // Check the validity of g because without a g during 711 // newosproc0. 712 if gp != nil { 713 r, _ := syscall4(&libpthread_create, uintptr(unsafe.Pointer(tid)), uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(fn)), uintptr(arg)) 714 return int32(r) 715 } 716 717 return pthread_create1(uintptr(unsafe.Pointer(tid)), uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(fn)), uintptr(arg)) 718 } 719 720 // On multi-thread program, sigprocmask must not be called. 721 // It's replaced by sigthreadmask. 722 func sigprocmask1(how, new, old uintptr) 723 724 //go:nosplit 725 func sigprocmask(how int32, new, old *sigset) { 726 gp := getg() 727 728 // Check the validity of m because it might be called during a cgo 729 // callback early enough where m isn't available yet. 730 if gp != nil && gp.m != nil { 731 r, err := syscall3(&libpthread_sigthreadmask, uintptr(how), uintptr(unsafe.Pointer(new)), uintptr(unsafe.Pointer(old))) 732 if int32(r) != 0 { 733 println("syscall sigthreadmask failed: ", hex(err)) 734 throw("syscall sigthreadmask") 735 } 736 return 737 } 738 sigprocmask1(uintptr(how), uintptr(unsafe.Pointer(new)), uintptr(unsafe.Pointer(old))) 739 740 } 741 742 //go:nosplit 743 func pthread_self() pthread { 744 r, _ := syscall0(&libpthread_self) 745 return pthread(r) 746 } 747 748 //go:nosplit 749 func signalM(mp *m, sig int) { 750 syscall2(&libpthread_kill, uintptr(pthread(mp.procid)), uintptr(sig)) 751 }