1
0
mirror of https://github.com/golang/go synced 2024-09-29 15:34:30 -06:00

runtime: avoid new linkname for goroutine profiles

CL 464349 added a new linkname to provide gcount to runtime/pprof to
avoid a STW when estimating the goroutine profile allocation size.

However, adding a linkname here isn't necessary for a few reasons:

1. We already export gcount via NumGoroutines. I completely forgot about
   this during review.
2. aktau suggested that goroutineProfileWithLabelsConcurrent return
   gcount as a fast path estimate when the input is empty.

The second point keeps the code cleaner overall, so I've done that.

For #54014.

Change-Id: I6cb0811a769c805e269b55774cdd43509854078e
Reviewed-on: https://go-review.googlesource.com/c/go/+/559515
Auto-Submit: Michael Pratt <mpratt@google.com>
Auto-Submit: Nicolas Hillegeer <aktau@google.com>
Reviewed-by: Nicolas Hillegeer <aktau@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Michael Pratt 2024-01-30 11:01:05 -05:00 committed by Gopher Robot
parent b89ad46451
commit 65f056d07a
2 changed files with 9 additions and 14 deletions

View File

@ -1131,12 +1131,15 @@ func (p *goroutineProfileStateHolder) CompareAndSwap(old, new goroutineProfileSt
return (*atomic.Uint32)(p).CompareAndSwap(uint32(old), uint32(new))
}
//go:linkname runtime_gcount runtime/pprof.runtime_gcount
func runtime_gcount() int {
return int(gcount())
}
func goroutineProfileWithLabelsConcurrent(p []StackRecord, labels []unsafe.Pointer) (n int, ok bool) {
if len(p) == 0 {
// An empty slice is obviously too small. Return a rough
// allocation estimate without bothering to STW. As long as
// this is close, then we'll only need to STW once (on the next
// call).
return int(gcount()), false
}
semacquire(&goroutineProfile.sema)
ourg := getg()

View File

@ -755,9 +755,6 @@ func writeGoroutineStacks(w io.Writer) error {
return err
}
// runtime_gcount is defined in runtime/mprof.go
func runtime_gcount() (n int)
func writeRuntimeProfile(w io.Writer, debug int, name string, fetch func([]runtime.StackRecord, []unsafe.Pointer) (int, bool)) error {
// Find out how many records there are (fetch(nil)),
// allocate that many records, and get the data.
@ -767,12 +764,7 @@ func writeRuntimeProfile(w io.Writer, debug int, name string, fetch func([]runti
// The loop should only execute one iteration in the common case.
var p []runtime.StackRecord
var labels []unsafe.Pointer
var n, ok = 0, false
if name == "goroutine" {
n = runtime_gcount()
} else {
n, ok = fetch(nil, nil)
}
n, ok := fetch(nil, nil)
for {
// Allocate room for a slightly bigger profile,