]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: avoid divide-by-zero in GC trigger controller
authorAustin Clements <austin@google.com>
Tue, 21 Apr 2015 17:46:54 +0000 (13:46 -0400)
committerAustin Clements <austin@google.com>
Wed, 22 Apr 2015 19:07:36 +0000 (19:07 +0000)
The trigger controller computes GC CPU utilization by dividing by the
wall-clock time that's passed since concurrent mark began. Since this
delta is nanoseconds it's borderline impossible for it to be zero, but
if it is zero we'll currently divide by zero. Be robust to this
possibility by ignoring the utilization in the error term if no time
has elapsed.

Change-Id: I93dfc9e84735682af3e637f6538d1e7602634f09
Reviewed-on: https://go-review.googlesource.com/9175
Reviewed-by: Rick Hudson <rlh@golang.org>
src/runtime/mgc.go

index 100fbf0b1c39728561bbf00d7fdbf3c747d2668e..0e4f7cb81b921d2391434df0f39b96bc8c04ee7d 100644 (file)
@@ -424,7 +424,15 @@ func (c *gcControllerState) endCycle() {
        goalGrowthRatio := float64(gcpercent) / 100
        actualGrowthRatio := float64(memstats.heap_live)/float64(memstats.heap_marked) - 1
        duration := nanotime() - c.bgMarkStartTime
-       utilization := float64(c.assistTime+c.dedicatedMarkTime+c.fractionalMarkTime) / float64(duration*int64(gomaxprocs))
+       var utilization float64
+       if duration <= 0 {
+               // Avoid divide-by-zero computing utilization. This
+               // has the effect of ignoring the utilization in the
+               // error term.
+               utilization = gcGoalUtilization
+       } else {
+               utilization = float64(c.assistTime+c.dedicatedMarkTime+c.fractionalMarkTime) / float64(duration*int64(gomaxprocs))
+       }
        triggerError := goalGrowthRatio - c.triggerRatio - utilization/gcGoalUtilization*(actualGrowthRatio-c.triggerRatio)
 
        // Finally, we adjust the trigger for next time by this error,