mirror of
https://github.com/golang/go.git
synced 2025-05-27 18:31:35 +00:00
runtime: make NumGoroutine and Stack agree not to include system goroutines
Before, NumGoroutine counted system goroutines and Stack (usually) didn't show them, which was inconsistent and confusing. To resolve which way they should be consistent, it seems like package main import "runtime" func main() { println(runtime.NumGoroutine()) } should print 1 regardless of internal runtime details. Make it so. Fixes #11706. Change-Id: I6bfe26a901de517728192cfb26a5568c4ef4fe47 Reviewed-on: https://go-review.googlesource.com/18343 Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
parent
20d745c57c
commit
c5bafc8281
@ -576,12 +576,17 @@ func Stack(buf []byte, all bool) int {
|
||||
pc := getcallerpc(unsafe.Pointer(&buf))
|
||||
systemstack(func() {
|
||||
g0 := getg()
|
||||
// Force traceback=1 to override GOTRACEBACK setting,
|
||||
// so that Stack's results are consistent.
|
||||
// GOTRACEBACK is only about crash dumps.
|
||||
g0.m.traceback = 1
|
||||
g0.writebuf = buf[0:0:len(buf)]
|
||||
goroutineheader(gp)
|
||||
traceback(pc, sp, 0, gp)
|
||||
if all {
|
||||
tracebackothers(gp)
|
||||
}
|
||||
g0.m.traceback = 0
|
||||
n = len(g0.writebuf)
|
||||
g0.writebuf = nil
|
||||
})
|
||||
|
@ -2162,6 +2162,9 @@ func goexit0(gp *g) {
|
||||
_g_ := getg()
|
||||
|
||||
casgstatus(gp, _Grunning, _Gdead)
|
||||
if isSystemGoroutine(gp) {
|
||||
atomic.Xadd(&sched.ngsys, -1)
|
||||
}
|
||||
gp.m = nil
|
||||
gp.lockedm = nil
|
||||
_g_.m.lockedg = nil
|
||||
@ -2693,6 +2696,9 @@ func newproc1(fn *funcval, argp *uint8, narg int32, nret int32, callerpc uintptr
|
||||
gostartcallfn(&newg.sched, fn)
|
||||
newg.gopc = callerpc
|
||||
newg.startpc = fn.fn
|
||||
if isSystemGoroutine(newg) {
|
||||
atomic.Xadd(&sched.ngsys, +1)
|
||||
}
|
||||
casgstatus(newg, _Gdead, _Grunnable)
|
||||
|
||||
if _p_.goidcache == _p_.goidcacheend {
|
||||
@ -2885,7 +2891,7 @@ func badunlockosthread() {
|
||||
}
|
||||
|
||||
func gcount() int32 {
|
||||
n := int32(allglen) - sched.ngfree
|
||||
n := int32(allglen) - sched.ngfree - int32(atomic.Load(&sched.ngsys))
|
||||
for i := 0; ; i++ {
|
||||
_p_ := allp[i]
|
||||
if _p_ == nil {
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"net"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
@ -336,6 +337,23 @@ func TestGCFairness(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNumGoroutine(t *testing.T) {
|
||||
output := runTestProg(t, "testprog", "NumGoroutine")
|
||||
want := "1\n"
|
||||
if output != want {
|
||||
t.Fatalf("want %q, got %q", want, output)
|
||||
}
|
||||
|
||||
buf := make([]byte, 1<<20)
|
||||
buf = buf[:runtime.Stack(buf, true)]
|
||||
|
||||
n := runtime.NumGoroutine()
|
||||
|
||||
if nstk := strings.Count(string(buf), "goroutine "); n != nstk {
|
||||
t.Fatalf("NumGoroutine=%d, but found %d goroutines in stack dump", n, nstk)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPingPongHog(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping in -short mode")
|
||||
|
@ -418,6 +418,8 @@ type schedt struct {
|
||||
mcount int32 // number of m's that have been created
|
||||
maxmcount int32 // maximum number of m's allowed (or die)
|
||||
|
||||
ngsys uint32 // number of system goroutines; updated atomically
|
||||
|
||||
pidle puintptr // idle p's
|
||||
npidle uint32
|
||||
nmspinning uint32 // See "Worker thread parking/unparking" comment in proc.go.
|
||||
|
15
src/runtime/testdata/testprog/misc.go
vendored
Normal file
15
src/runtime/testdata/testprog/misc.go
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import "runtime"
|
||||
|
||||
func init() {
|
||||
register("NumGoroutine", NumGoroutine)
|
||||
}
|
||||
|
||||
func NumGoroutine() {
|
||||
println(runtime.NumGoroutine())
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user