diff options
author | Keith Randall <khr@golang.org> | 2014-09-16 17:26:16 -0700 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2014-09-16 17:26:16 -0700 |
commit | da8cf5438aa676a99e8bb55c94011b2581743e1a (patch) | |
tree | c5ce0da4ace36faa3cae7e0a8f1891251cc0cfba /src/runtime/debug.go | |
parent | e28746c44494030e9b44aa523cd5a21ebfe39ff5 (diff) | |
download | go-da8cf5438aa676a99e8bb55c94011b2581743e1a.tar.gz go-da8cf5438aa676a99e8bb55c94011b2581743e1a.zip |
runtime: always run semacquire on the G stack
semacquire might need to park the currently running G. It can
only park if called from the G stack (because it has no way of
saving the M stack state). So all calls to semacquire must come
from the G stack.
The three violators are GOMAXPROCS, ReadMemStats, and WriteHeapDump.
This change moves the semacquire call earlier, out of their C code
and into their Go code.
This seldom caused bugs because semacquire seldom actually had
to park the caller. But it did happen intermittently.
Fixes #8749
LGTM=dvyukov
R=golang-codereviews, dvyukov, bradfitz
CC=golang-codereviews
https://golang.org/cl/144940043
Diffstat (limited to 'src/runtime/debug.go')
-rw-r--r-- | src/runtime/debug.go | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/src/runtime/debug.go b/src/runtime/debug.go index bb4bd60ed4..4414dd55d2 100644 --- a/src/runtime/debug.go +++ b/src/runtime/debug.go @@ -24,15 +24,29 @@ func UnlockOSThread() // The number of logical CPUs on the local machine can be queried with NumCPU. // This call will go away when the scheduler improves. func GOMAXPROCS(n int) int { - g := getg() - g.m.scalararg[0] = uintptr(n) - onM(gomaxprocs_m) - n = int(g.m.scalararg[0]) - g.m.scalararg[0] = 0 - return n -} + if n > _MaxGomaxprocs { + n = _MaxGomaxprocs + } + lock(&sched.lock) + ret := int(gomaxprocs) + unlock(&sched.lock) + if n <= 0 || n == ret { + return ret + } -func gomaxprocs_m() // proc.c + semacquire(&worldsema, false) + gp := getg() + gp.m.gcing = 1 + onM(stoptheworld) + + // newprocs will be processed by starttheworld + newprocs = int32(n) + + gp.m.gcing = 0 + semrelease(&worldsema) + onM(starttheworld) + return ret +} // NumCPU returns the number of logical CPUs on the local machine. func NumCPU() int { |