diff options
author | Clément Chigot <clement.chigot@atos.net> | 2019-03-25 10:31:30 +0100 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2019-03-27 17:22:11 +0000 |
commit | 38dc177d3ac5b5a8cb6b7f9039144cbe8bd58036 (patch) | |
tree | e5fad95d9ef8d6a87ee631ac49a2ff7529a10fad /src/runtime/os_aix.go | |
parent | 53c9c068115168ebcc1e649fa7a15a804a99d92f (diff) | |
download | go-38dc177d3ac5b5a8cb6b7f9039144cbe8bd58036.tar.gz go-38dc177d3ac5b5a8cb6b7f9039144cbe8bd58036.zip |
runtime: create library startup for aix/ppc64
As .init_array section aren't available on AIX, the Go runtime
initialization is made with gcc constructor attribute.
However, as cgo tool is building a binary in order to get imported
C symbols, Go symbols imported for this initilization must be ignored.
-Wl,-berok is mandatory otherwize ld will fail to create this binary,
_rt0_aix_ppc64_lib and runtime_rt0_go aren't defined in runtime/cgo.
These two symbols must also be ignored when creating _cgo_import.go.
Change-Id: Icf2e0282f5b50de5fa82007439a428e6147efef1
Reviewed-on: https://go-review.googlesource.com/c/go/+/169118
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/runtime/os_aix.go')
-rw-r--r-- | src/runtime/os_aix.go | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/src/runtime/os_aix.go b/src/runtime/os_aix.go index 45c7174e05..faec9ac113 100644 --- a/src/runtime/os_aix.go +++ b/src/runtime/os_aix.go @@ -97,6 +97,66 @@ func osinit() { setupSystemConf() } +// newosproc0 is a version of newosproc that can be called before the runtime +// is initialized. +// +// This function is not safe to use after initialization as it does not pass an M as fnarg. +// +//go:nosplit +func newosproc0(stacksize uintptr, fn *funcDescriptor) { + var ( + attr pthread_attr + oset sigset + tid pthread + ) + + if pthread_attr_init(&attr) != 0 { + write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate))) + exit(1) + } + + if pthread_attr_setstacksize(&attr, threadStackSize) != 0 { + write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate))) + exit(1) + } + + if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 { + write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate))) + exit(1) + } + + // Disable signals during create, so that the new thread starts + // with signals disabled. It will enable them in minit. + sigprocmask(_SIG_SETMASK, &sigset_all, &oset) + var ret int32 + for tries := 0; tries < 20; tries++ { + // pthread_create can fail with EAGAIN for no reasons + // but it will be ok if it retries. + ret = pthread_create(&tid, &attr, fn, nil) + if ret != _EAGAIN { + break + } + usleep(uint32(tries+1) * 1000) // Milliseconds. + } + sigprocmask(_SIG_SETMASK, &oset, nil) + if ret != 0 { + write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate))) + exit(1) + } + +} + +var failthreadcreate = []byte("runtime: failed to create new OS thread\n") + +// Called to do synchronous initialization of Go code built with +// -buildmode=c-archive or -buildmode=c-shared. +// None of the Go runtime is initialized. +//go:nosplit +//go:nowritebarrierrec +func libpreinit() { + initsig(true) +} + // Ms related functions func mpreinit(mp *m) { mp.gsignal = malg(32 * 1024) // AIX wants >= 8K @@ -213,7 +273,13 @@ func setsig(i uint32, fn uintptr) { //go:nosplit //go:nowritebarrierrec func setsigstack(i uint32) { - throw("Not yet implemented\n") + var sa sigactiont + sigaction(uintptr(i), nil, &sa) + if sa.sa_flags&_SA_ONSTACK != 0 { + return + } + sa.sa_flags |= _SA_ONSTACK + sigaction(uintptr(i), &sa, nil) } //go:nosplit |