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