mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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
This commit is contained in:
parent
e28746c444
commit
da8cf5438a
9 changed files with 114 additions and 132 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue