aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/os_aix.go
diff options
context:
space:
mode:
authorClément Chigot <clement.chigot@atos.net>2019-03-25 10:31:30 +0100
committerIan Lance Taylor <iant@golang.org>2019-03-27 17:22:11 +0000
commit38dc177d3ac5b5a8cb6b7f9039144cbe8bd58036 (patch)
treee5fad95d9ef8d6a87ee631ac49a2ff7529a10fad /src/runtime/os_aix.go
parent53c9c068115168ebcc1e649fa7a15a804a99d92f (diff)
downloadgo-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.go68
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