From 5ec2427357f4917d0aad40cffddeea73e580129e Mon Sep 17 00:00:00 2001 From: Michael Knyszek Date: Fri, 1 Oct 2021 15:07:45 -0400 Subject: [PATCH] runtime: pass nanotime and gomaxprocs into startCycle and endCycle explicitly This is to facilitate testing of the pacer, since otherwise this is accessing global state, which is impossible to stub out properly. For #44167. Change-Id: I52c3b51fc0ffff38e3bbe534bd66e5761c0003a8 Reviewed-on: https://go-review.googlesource.com/c/go/+/353353 Trust: Michael Knyszek Run-TryBot: Michael Knyszek TryBot-Result: Go Bot Reviewed-by: Michael Pratt --- src/runtime/mgc.go | 4 ++-- src/runtime/mgcpacer.go | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go index cf53585dcde1ef..03711a9617da03 100644 --- a/src/runtime/mgc.go +++ b/src/runtime/mgc.go @@ -663,7 +663,7 @@ func gcStart(trigger gcTrigger) { // Assists and workers can start the moment we start // the world. - gcController.startCycle(now) + gcController.startCycle(now, int(gomaxprocs)) work.heapGoal = gcController.heapGoal // In STW mode, disable scheduling of user Gs. This may also @@ -889,7 +889,7 @@ top: // endCycle depends on all gcWork cache stats being flushed. // The termination algorithm above ensured that up to // allocations since the ragged barrier. - nextTriggerRatio := gcController.endCycle(work.userForced) + nextTriggerRatio := gcController.endCycle(now, int(gomaxprocs), work.userForced) // Perform mark termination. This will restart the world. gcMarkTermination(nextTriggerRatio) diff --git a/src/runtime/mgcpacer.go b/src/runtime/mgcpacer.go index ad7c4bb840dfe1..160383db43712d 100644 --- a/src/runtime/mgcpacer.go +++ b/src/runtime/mgcpacer.go @@ -290,7 +290,7 @@ func (c *gcControllerState) init(gcPercent int32) { // startCycle resets the GC controller's state and computes estimates // for a new GC cycle. The caller must hold worldsema and the world // must be stopped. -func (c *gcControllerState) startCycle(markStartTime int64) { +func (c *gcControllerState) startCycle(markStartTime int64, procs int) { c.scanWork = 0 c.bgScanCredit = 0 c.assistTime = 0 @@ -316,7 +316,7 @@ func (c *gcControllerState) startCycle(markStartTime int64) { // dedicated workers so that the utilization is closest to // 25%. For small GOMAXPROCS, this would introduce too much // error, so we add fractional workers in that case. - totalUtilizationGoal := float64(gomaxprocs) * gcBackgroundUtilization + totalUtilizationGoal := float64(procs) * gcBackgroundUtilization c.dedicatedMarkWorkersNeeded = int64(totalUtilizationGoal + 0.5) utilError := float64(c.dedicatedMarkWorkersNeeded)/totalUtilizationGoal - 1 const maxUtilError = 0.3 @@ -329,14 +329,14 @@ func (c *gcControllerState) startCycle(markStartTime int64) { // Too many dedicated workers. c.dedicatedMarkWorkersNeeded-- } - c.fractionalUtilizationGoal = (totalUtilizationGoal - float64(c.dedicatedMarkWorkersNeeded)) / float64(gomaxprocs) + c.fractionalUtilizationGoal = (totalUtilizationGoal - float64(c.dedicatedMarkWorkersNeeded)) / float64(procs) } else { c.fractionalUtilizationGoal = 0 } // In STW mode, we just want dedicated workers. if debug.gcstoptheworld > 0 { - c.dedicatedMarkWorkersNeeded = int64(gomaxprocs) + c.dedicatedMarkWorkersNeeded = int64(procs) c.fractionalUtilizationGoal = 0 } @@ -464,7 +464,7 @@ func (c *gcControllerState) revise() { // endCycle computes the trigger ratio for the next cycle. // userForced indicates whether the current GC cycle was forced // by the application. -func (c *gcControllerState) endCycle(userForced bool) float64 { +func (c *gcControllerState) endCycle(now int64, procs int, userForced bool) float64 { // Record last heap goal for the scavenger. // We'll be updating the heap goal soon. gcController.lastHeapGoal = gcController.heapGoal @@ -495,13 +495,13 @@ func (c *gcControllerState) endCycle(userForced bool) float64 { // heap growth is the error. goalGrowthRatio := c.effectiveGrowthRatio() actualGrowthRatio := float64(c.heapLive)/float64(c.heapMarked) - 1 - assistDuration := nanotime() - c.markStartTime + assistDuration := now - c.markStartTime // Assume background mark hit its utilization goal. utilization := gcBackgroundUtilization // Add assist utilization; avoid divide by zero. if assistDuration > 0 { - utilization += float64(c.assistTime) / float64(assistDuration*int64(gomaxprocs)) + utilization += float64(c.assistTime) / float64(assistDuration*int64(procs)) } triggerError := goalGrowthRatio - c.triggerRatio - utilization/gcGoalUtilization*(actualGrowthRatio-c.triggerRatio)