diff options
| author | Russ Cox <rsc@golang.org> | 2023-06-26 17:12:44 -0400 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2023-08-17 01:30:31 +0000 |
| commit | 1c0035401358c8bfc2ff646b1d950da5fcd6b355 (patch) | |
| tree | b446e570234778b0d89924fd70ab7a16b4542411 /src/runtime/runtime2.go | |
| parent | 14a3ffc3d2165ef03c3ffd0037a4fa6dbb776026 (diff) | |
| download | go-1c0035401358c8bfc2ff646b1d950da5fcd6b355.tar.xz | |
runtime: change mutex profile to count every blocked goroutine
The pprof mutex profile was meant to match the Google C++ (now Abseil)
mutex profiler, originally designed and implemented by Mike Burrows.
When we worked on the Go version, pjw and I missed that C++ counts the
time each thread is blocked, even if multiple threads are blocked on a
mutex. That is, if 100 threads are blocked on the same mutex for the
same 10ms, that still counts as 1000ms of contention in C++. In Go, to
date, /debug/pprof/mutex has counted that as only 10ms of contention.
If 100 goroutines are blocked on one mutex and only 1 goroutine is
blocked on another mutex, we probably do want to see the first mutex
as being more contended, so the Abseil approach is the more useful one.
This CL adopts "contention scales with number of goroutines blocked",
to better match Abseil [1]. However, it still makes sure to attribute the
time to the unlock that caused the backup, not subsequent innocent
unlocks that were affected by the congestion. In this way it still gives
more accurate profiles than Abseil does.
[1] https://github.com/abseil/abseil-cpp/blob/lts_2023_01_25/absl/synchronization/mutex.cc#L2390
Fixes #61015.
Change-Id: I7eb9e706867ffa8c0abb5b26a1b448f6eba49331
Reviewed-on: https://go-review.googlesource.com/c/go/+/506415
Run-TryBot: Russ Cox <rsc@golang.org>
Auto-Submit: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/runtime/runtime2.go')
| -rw-r--r-- | src/runtime/runtime2.go | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go index 5017a7a80a..2a02e1fb3b 100644 --- a/src/runtime/runtime2.go +++ b/src/runtime/runtime2.go @@ -342,7 +342,7 @@ type gobuf struct { bp uintptr // for framepointer-enabled architectures } -// sudog represents a g in a wait list, such as for sending/receiving +// sudog (pseudo-g) represents a g in a wait list, such as for sending/receiving // on a channel. // // sudog is necessary because the g ↔ synchronization object relation @@ -382,6 +382,13 @@ type sudog struct { // because c was closed. success bool + // waiters is a count of semaRoot waiting list other than head of list, + // clamped to a uint16 to fit in unused space. + // Only meaningful at the head of the list. + // (If we wanted to be overly clever, we could store a high 16 bits + // in the second entry in the list.) + waiters uint16 + parent *sudog // semaRoot binary tree waitlink *sudog // g.waiting list or semaRoot waittail *sudog // semaRoot |
