aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/debug.go
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2014-09-16 17:26:16 -0700
committerKeith Randall <khr@golang.org>2014-09-16 17:26:16 -0700
commitda8cf5438aa676a99e8bb55c94011b2581743e1a (patch)
treec5ce0da4ace36faa3cae7e0a8f1891251cc0cfba /src/runtime/debug.go
parente28746c44494030e9b44aa523cd5a21ebfe39ff5 (diff)
downloadgo-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.go30
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 {