diff options
author | Keith Randall <khr@golang.org> | 2018-05-03 10:30:31 -0700 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2018-05-19 17:38:01 +0000 |
commit | e86c26789dbc11c50c4c49bee55ea015847a97b7 (patch) | |
tree | a6c1cdd109f457edab95df6f29229595cb97a505 /src/runtime/os_darwin.go | |
parent | e9137299bf74e1bcac358b569f86aef73c7c2ea6 (diff) | |
download | go-e86c26789dbc11c50c4c49bee55ea015847a97b7.tar.gz go-e86c26789dbc11c50c4c49bee55ea015847a97b7.zip |
runtime: fix darwin 386/amd64 stack switches
A few libc_ calls were missing stack switches.
Unfortunately, adding the stack switches revealed a deeper problem.
systemstack() is fundamentally flawed because when you do
systemstack(func() { ... })
There's no way to mark the anonymous function as nosplit. At first I
thought it didn't matter, as that function runs on the g0 stack. But
nosplit is still required, because some syscalls are done when stack
bounds are not set up correctly (e.g. in a signal handler, which runs
on the g0 stack, but g is still pointing at the g stack). Instead use
asmcgocall and funcPC, so we can be nosplit all the way down.
Mid-stack inlining now pushes darwin over the nosplit limit also.
Leaving that as a TODO.
Update #23168
This might fix the cause of occasional darwin hangs.
Update #25181
Update #17490
Change-Id: If9c3ef052822c7679f5a1dd192443f714483327e
Reviewed-on: https://go-review.googlesource.com/111258
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/runtime/os_darwin.go')
-rw-r--r-- | src/runtime/os_darwin.go | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go index 613725115d..4df1fba17d 100644 --- a/src/runtime/os_darwin.go +++ b/src/runtime/os_darwin.go @@ -154,7 +154,7 @@ func newosproc(mp *m) { // setup and then calls mstart. var oset sigset sigprocmask(_SIG_SETMASK, &sigset_all, &oset) - _, err = pthread_create(&attr, funcPC(mstart_stub), unsafe.Pointer(mp)) + err = pthread_create(&attr, funcPC(mstart_stub), unsafe.Pointer(mp)) sigprocmask(_SIG_SETMASK, &oset, nil) if err != 0 { write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate))) @@ -175,21 +175,21 @@ func newosproc0(stacksize uintptr, fn uintptr) { // Initialize an attribute object. var attr pthreadattr var err int32 - err = pthread_attr_init_trampoline(&attr) + err = pthread_attr_init(&attr) if err != 0 { write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate))) exit(1) } // Set the stack we want to use. - if pthread_attr_setstacksize_trampoline(&attr, stacksize) != 0 { + if pthread_attr_setstacksize(&attr, stacksize) != 0 { write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate))) exit(1) } mSysStatInc(&memstats.stacks_sys, stacksize) // Tell the pthread library we won't join with this thread. - if pthread_attr_setdetachstate_trampoline(&attr, _PTHREAD_CREATE_DETACHED) != 0 { + if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 { write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate))) exit(1) } @@ -198,8 +198,7 @@ func newosproc0(stacksize uintptr, fn uintptr) { // setup and then calls mstart. var oset sigset sigprocmask(_SIG_SETMASK, &sigset_all, &oset) - var t pthread - err = pthread_create_trampoline(&t, &attr, fn, nil) + err = pthread_create(&attr, fn, nil) sigprocmask(_SIG_SETMASK, &oset, nil) if err != 0 { write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate))) |