Skip to content

Commit

Permalink
runtime: add a more stable isSystemGoroutine mode
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
aclements committed Oct 2, 2018
1 parent 198440c commit 29b21ec
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/runtime/heapdump.go
Expand Up @@ -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())
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/mprof.go
Expand Up @@ -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")
Expand Down
6 changes: 3 additions & 3 deletions src/runtime/proc.go
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
13 changes: 11 additions & 2 deletions src/runtime/traceback.go
Expand Up @@ -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")
Expand Down Expand Up @@ -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() {
Expand All @@ -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.")
Expand Down

0 comments on commit 29b21ec

Please sign in to comment.