From 14018c8becc385f79f62f9cdf24cab93fe3e0cdc Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 1 Nov 2022 16:04:50 -0700 Subject: 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 Auto-Submit: Ian Lance Taylor TryBot-Result: Gopher Robot Run-TryBot: Ian Lance Taylor Reviewed-by: Ian Lance Taylor --- src/runtime/os_linux.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src/runtime/os_linux.go') 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") -- cgit v1.3