mirror of
https://github.com/golang/go
synced 2024-09-19 07:52:34 +00:00
runtime: add a more stable isSystemGoroutine mode
Currently, isSystemGoroutine varies on whether it considers the finalizer goroutine a user goroutine or a system goroutine. For the next CL, we're going to want to always consider the finalier goroutine a user goroutine, so add a flag that indicates that. Updates #26903. This is preparation for unifying STW GC and concurrent GC. Change-Id: Iafc92e519c13d9f8d879332cb5f0d12164104c33 Reviewed-on: https://go-review.googlesource.com/c/134778 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
This commit is contained in:
parent
198440cc3d
commit
29b21ec4c3
|
@ -346,7 +346,7 @@ func dumpgoroutine(gp *g) {
|
|||
dumpint(uint64(gp.goid))
|
||||
dumpint(uint64(gp.gopc))
|
||||
dumpint(uint64(readgstatus(gp)))
|
||||
dumpbool(isSystemGoroutine(gp))
|
||||
dumpbool(isSystemGoroutine(gp, false))
|
||||
dumpbool(false) // isbackground
|
||||
dumpint(uint64(gp.waitsince))
|
||||
dumpstr(gp.waitreason.String())
|
||||
|
|
|
@ -723,7 +723,7 @@ func GoroutineProfile(p []StackRecord) (n int, ok bool) {
|
|||
isOK := func(gp1 *g) bool {
|
||||
// Checking isSystemGoroutine here makes GoroutineProfile
|
||||
// consistent with both NumGoroutine and Stack.
|
||||
return gp1 != gp && readgstatus(gp1) != _Gdead && !isSystemGoroutine(gp1)
|
||||
return gp1 != gp && readgstatus(gp1) != _Gdead && !isSystemGoroutine(gp1, false)
|
||||
}
|
||||
|
||||
stopTheWorld("profile")
|
||||
|
|
|
@ -2730,7 +2730,7 @@ func goexit0(gp *g) {
|
|||
_g_ := getg()
|
||||
|
||||
casgstatus(gp, _Grunning, _Gdead)
|
||||
if isSystemGoroutine(gp) {
|
||||
if isSystemGoroutine(gp, false) {
|
||||
atomic.Xadd(&sched.ngsys, -1)
|
||||
}
|
||||
gp.m = nil
|
||||
|
@ -3381,7 +3381,7 @@ func newproc1(fn *funcval, argp *uint8, narg int32, callergp *g, callerpc uintpt
|
|||
if _g_.m.curg != nil {
|
||||
newg.labels = _g_.m.curg.labels
|
||||
}
|
||||
if isSystemGoroutine(newg) {
|
||||
if isSystemGoroutine(newg, false) {
|
||||
atomic.Xadd(&sched.ngsys, +1)
|
||||
}
|
||||
newg.gcscanvalid = false
|
||||
|
@ -4244,7 +4244,7 @@ func checkdead() {
|
|||
lock(&allglock)
|
||||
for i := 0; i < len(allgs); i++ {
|
||||
gp := allgs[i]
|
||||
if isSystemGoroutine(gp) {
|
||||
if isSystemGoroutine(gp, false) {
|
||||
continue
|
||||
}
|
||||
s := readgstatus(gp)
|
||||
|
|
|
@ -945,7 +945,7 @@ func tracebackothers(me *g) {
|
|||
|
||||
lock(&allglock)
|
||||
for _, gp := range allgs {
|
||||
if gp == me || gp == g.m.curg || readgstatus(gp) == _Gdead || isSystemGoroutine(gp) && level < 2 {
|
||||
if gp == me || gp == g.m.curg || readgstatus(gp) == _Gdead || isSystemGoroutine(gp, false) && level < 2 {
|
||||
continue
|
||||
}
|
||||
print("\n")
|
||||
|
@ -1031,7 +1031,11 @@ func topofstack(f funcInfo, g0 bool) bool {
|
|||
// in stack dumps and deadlock detector. This is any goroutine that
|
||||
// starts at a runtime.* entry point, except for runtime.main and
|
||||
// sometimes runtime.runfinq.
|
||||
func isSystemGoroutine(gp *g) bool {
|
||||
//
|
||||
// If fixed is true, any goroutine that can vary between user and
|
||||
// system (that is, the finalizer goroutine) is considered a user
|
||||
// goroutine.
|
||||
func isSystemGoroutine(gp *g, fixed bool) bool {
|
||||
// Keep this in sync with cmd/trace/trace.go:isSystemGoroutine.
|
||||
f := findfunc(gp.startpc)
|
||||
if !f.valid() {
|
||||
|
@ -1043,6 +1047,11 @@ func isSystemGoroutine(gp *g) bool {
|
|||
if f.funcID == funcID_runfinq {
|
||||
// We include the finalizer goroutine if it's calling
|
||||
// back into user code.
|
||||
if fixed {
|
||||
// This goroutine can vary. In fixed mode,
|
||||
// always consider it a user goroutine.
|
||||
return false
|
||||
}
|
||||
return !fingRunning
|
||||
}
|
||||
return hasPrefix(funcname(f), "runtime.")
|
||||
|
|
Loading…
Reference in a new issue