aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/os_linux.go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2022-11-01 16:04:50 -0700
committerGopher Robot <gobot@golang.org>2022-11-10 20:44:45 +0000
commit14018c8becc385f79f62f9cdf24cab93fe3e0cdc (patch)
tree74490921a6f54463f4b3d561afb5190ebe75f9b1 /src/runtime/os_linux.go
parentd96eb826cb7cd4fe36745e3b1a79e0a2571acc4a (diff)
downloadgo-14018c8becc385f79f62f9cdf24cab93fe3e0cdc.tar.xz
runtime: retry thread creation on EAGAIN
This copies the logic we use in runtime/cgo, when calling pthread_create, into runtime proper, when calling newosproc. We only do this in newosproc, not newosproc0, because in newosproc0 we need a nosplit function literal, and we need to pass arguments to it through newosproc, which is a pain. Also newosproc0 is only called at process startup, when thread creation is less likely to fail anyhow. Fixes #49438 Change-Id: Ia26813952fdbae8aaad5904c9102269900a07ba9 Reviewed-on: https://go-review.googlesource.com/c/go/+/447175 Reviewed-by: Michael Knyszek <mknyszek@google.com> Auto-Submit: Ian Lance Taylor <iant@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Ian Lance Taylor <iant@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com>
Diffstat (limited to 'src/runtime/os_linux.go')
-rw-r--r--src/runtime/os_linux.go16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/runtime/os_linux.go b/src/runtime/os_linux.go
index 8e30ee338e..3ad1e3b8fc 100644
--- a/src/runtime/os_linux.go
+++ b/src/runtime/os_linux.go
@@ -176,12 +176,20 @@ func newosproc(mp *m) {
// with signals disabled. It will enable them in minit.
var oset sigset
sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
- ret := clone(cloneFlags, stk, unsafe.Pointer(mp), unsafe.Pointer(mp.g0), unsafe.Pointer(abi.FuncPCABI0(mstart)))
+ ret := retryOnEAGAIN(func() int32 {
+ r := clone(cloneFlags, stk, unsafe.Pointer(mp), unsafe.Pointer(mp.g0), unsafe.Pointer(abi.FuncPCABI0(mstart)))
+ // clone returns positive TID, negative errno.
+ // We don't care about the TID.
+ if r >= 0 {
+ return 0
+ }
+ return -r
+ })
sigprocmask(_SIG_SETMASK, &oset, nil)
- if ret < 0 {
- print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", -ret, ")\n")
- if ret == -_EAGAIN {
+ if ret != 0 {
+ print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", ret, ")\n")
+ if ret == _EAGAIN {
println("runtime: may need to increase max user processes (ulimit -u)")
}
throw("newosproc")