]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: add a more stable isSystemGoroutine mode
authorAustin Clements <austin@google.com>
Mon, 13 Aug 2018 20:08:03 +0000 (16:08 -0400)
committerAustin Clements <austin@google.com>
Tue, 2 Oct 2018 20:35:28 +0000 (20:35 +0000)
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>
src/runtime/heapdump.go
src/runtime/mprof.go
src/runtime/proc.go
src/runtime/traceback.go

index e2c6f18714d1ee8c88a3d3a288cc7e21b285c4a2..eadbcaeee12b7ccaddcfe3120bb3a911367b9dd2 100644 (file)
@@ -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())
index 43e4810d978786c00f0bcb1d99ab9e14770137bc..2bd41b650f4f791e1552b4fd1293613ccedcf75b 100644 (file)
@@ -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")
index ec73b4d918cae87bf2892515369dd07b18aaec4e..c477910c9e7e5bf55a7273b5650d8f706618a5f4 100644 (file)
@@ -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)
index 8e104ae89e79b523e1592be1636949835cb4a7e0..69d5764c8f7dc59f71097859f9a8d35b280f5a9b 100644 (file)
@@ -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.")