]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: only trigger forced GC if GC is not running
authorAustin Clements <austin@google.com>
Mon, 14 Dec 2015 22:25:28 +0000 (17:25 -0500)
committerAustin Clements <austin@google.com>
Tue, 15 Dec 2015 20:13:19 +0000 (20:13 +0000)
Currently, sysmon triggers a forced GC solely based on
memstats.last_gc. However, memstats.last_gc isn't updated until mark
termination, so once sysmon starts triggering forced GC, it will keep
triggering them until GC finishes. The first of these actually starts
a GC; the remainder up to the last print "GC forced", but gcStart
returns immediately because gcphase != _GCoff; then the last may start
another GC if the previous GC finishes (and sets last_gc) between
sysmon triggering it and gcStart checking the GC phase.

Fix this by expanding the condition for starting a forced GC to also
require that no GC is currently running. This, combined with the way
forcegchelper blocks until the GC cycle is started, ensures sysmon
only starts one GC when the time exceeds the forced GC threshold.

Fixes #13458.

Change-Id: Ie6cf841927f6085136be3f45259956cd5cf10d23
Reviewed-on: https://go-review.googlesource.com/17819
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
src/runtime/proc.go

index ade4d1143334c3fa2c3a26295e2b1f61cbc8973b..d75af10206e7da2ce01f2a9ce1354e863e065513 100644 (file)
@@ -3474,7 +3474,7 @@ func sysmon() {
                }
                // check if we need to force a GC
                lastgc := int64(atomic.Load64(&memstats.last_gc))
-               if lastgc != 0 && unixnow-lastgc > forcegcperiod && atomic.Load(&forcegc.idle) != 0 {
+               if gcphase == _GCoff && lastgc != 0 && unixnow-lastgc > forcegcperiod && atomic.Load(&forcegc.idle) != 0 {
                        lock(&forcegc.lock)
                        forcegc.idle = 0
                        forcegc.g.schedlink = 0