mirror of https://github.com/golang/go.git
runtime: create wrappers for gcDrain to identify time in profiles
Currently it's impossible to identify in profiles where gcDrain-related time is coming from. More specifically, what kind of worker. Create trivial wrappers for each worker so that the difference shows up in stack traces. Also, clarify why gcDrain disables write barriers. Change-Id: I966e3c0b1c583994e691f486bf0ed8cabb91dbbb Reviewed-on: https://go-review.googlesource.com/c/go/+/521815 Reviewed-by: Austin Clements <austin@google.com> Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
e68c027204
commit
081d27a2e5
|
|
@ -1383,7 +1383,7 @@ func gcBgMarkWorker() {
|
|||
default:
|
||||
throw("gcBgMarkWorker: unexpected gcMarkWorkerMode")
|
||||
case gcMarkWorkerDedicatedMode:
|
||||
gcDrain(&pp.gcw, gcDrainUntilPreempt|gcDrainFlushBgCredit)
|
||||
gcDrainMarkWorkerDedicated(&pp.gcw, true)
|
||||
if gp.preempt {
|
||||
// We were preempted. This is
|
||||
// a useful signal to kick
|
||||
|
|
@ -1398,11 +1398,11 @@ func gcBgMarkWorker() {
|
|||
}
|
||||
// Go back to draining, this time
|
||||
// without preemption.
|
||||
gcDrain(&pp.gcw, gcDrainFlushBgCredit)
|
||||
gcDrainMarkWorkerDedicated(&pp.gcw, false)
|
||||
case gcMarkWorkerFractionalMode:
|
||||
gcDrain(&pp.gcw, gcDrainFractional|gcDrainUntilPreempt|gcDrainFlushBgCredit)
|
||||
gcDrainMarkWorkerFractional(&pp.gcw)
|
||||
case gcMarkWorkerIdleMode:
|
||||
gcDrain(&pp.gcw, gcDrainIdle|gcDrainUntilPreempt|gcDrainFlushBgCredit)
|
||||
gcDrainMarkWorkerIdle(&pp.gcw)
|
||||
}
|
||||
casgstatus(gp, _Gwaiting, _Grunning)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1011,6 +1011,28 @@ const (
|
|||
gcDrainFractional
|
||||
)
|
||||
|
||||
// gcDrainMarkWorkerIdle is a wrapper for gcDrain that exists to better account
|
||||
// mark time in profiles.
|
||||
func gcDrainMarkWorkerIdle(gcw *gcWork) {
|
||||
gcDrain(gcw, gcDrainIdle|gcDrainUntilPreempt|gcDrainFlushBgCredit)
|
||||
}
|
||||
|
||||
// gcDrainMarkWorkerDedicated is a wrapper for gcDrain that exists to better account
|
||||
// mark time in profiles.
|
||||
func gcDrainMarkWorkerDedicated(gcw *gcWork, untilPreempt bool) {
|
||||
flags := gcDrainFlushBgCredit
|
||||
if untilPreempt {
|
||||
flags |= gcDrainUntilPreempt
|
||||
}
|
||||
gcDrain(gcw, flags)
|
||||
}
|
||||
|
||||
// gcDrainMarkWorkerFractional is a wrapper for gcDrain that exists to better account
|
||||
// mark time in profiles.
|
||||
func gcDrainMarkWorkerFractional(gcw *gcWork) {
|
||||
gcDrain(gcw, gcDrainFractional|gcDrainUntilPreempt|gcDrainFlushBgCredit)
|
||||
}
|
||||
|
||||
// gcDrain scans roots and objects in work buffers, blackening grey
|
||||
// objects until it is unable to get more work. It may return before
|
||||
// GC is done; it's the caller's responsibility to balance work from
|
||||
|
|
@ -1032,6 +1054,14 @@ const (
|
|||
//
|
||||
// gcDrain will always return if there is a pending STW.
|
||||
//
|
||||
// Disabling write barriers is necessary to ensure that after we've
|
||||
// confirmed that we've drained gcw, that we don't accidentally end
|
||||
// up flipping that condition by immediately adding work in the form
|
||||
// of a write barrier buffer flush.
|
||||
//
|
||||
// Don't set nowritebarrierrec because it's safe for some callees to
|
||||
// have write barriers enabled.
|
||||
//
|
||||
//go:nowritebarrier
|
||||
func gcDrain(gcw *gcWork, flags gcDrainFlags) {
|
||||
if !writeBarrier.needed {
|
||||
|
|
|
|||
Loading…
Reference in New Issue