aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2016-03-01 15:09:24 -0500
committerAndrew Gerrand <adg@golang.org>2016-04-14 05:23:47 +0000
commitaf1905781aa7a491b7ed85fff0b7fb0ccd030d2a (patch)
tree7cedb9e15f8045d623181f840c0d8371127885c6
parent85f28edd58581554b4250b769d2a0bc805be6fb2 (diff)
downloadgo-af1905781aa7a491b7ed85fff0b7fb0ccd030d2a.tar.gz
go-af1905781aa7a491b7ed85fff0b7fb0ccd030d2a.zip
runtime: reset mark state before stopping the world
Currently we reset the mark state during STW sweep termination. This involves looping over all of the goroutines. Each iteration of this loop takes ~25ns, so at around 400k goroutines, we'll exceed our 10ms pause goal. However, it's safe to do this before we stop the world for sweep termination because nothing is consuming this state yet. Hence, move the reset to just before STW. This isn't perfect: a long reset can still delay allocating goroutines that block on GC starting. But it's certainly better to block some things eventually than to block everything immediately. For 1.6.x. Fixes #14420. name \ 95%ile-time/sweepTerm old new delta 500kIdleGs-12 11312µs ± 6% 18.9µs ± 6% -99.83% (p=0.000 n=16+20) Change-Id: I9815c4d8d9b0d3c3e94dfdab78049cefe0dcc93c Reviewed-on: https://go-review.googlesource.com/20147 Reviewed-by: Rick Hudson <rlh@golang.org> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-on: https://go-review.googlesource.com/22043 Reviewed-by: Austin Clements <austin@google.com>
-rw-r--r--src/runtime/mgc.go11
1 files changed, 7 insertions, 4 deletions
diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go
index 94301c6dc7..1b95df9cbe 100644
--- a/src/runtime/mgc.go
+++ b/src/runtime/mgc.go
@@ -932,6 +932,9 @@ func gcStart(mode gcMode, forceTrigger bool) {
if mode == gcBackgroundMode {
gcBgMarkStartWorkers()
}
+
+ gcResetMarkState()
+
now := nanotime()
work.stwprocs, work.maxprocs = gcprocs(), gomaxprocs
work.tSweepTerm = now
@@ -949,8 +952,6 @@ func gcStart(mode gcMode, forceTrigger bool) {
// reclaimed until the next GC cycle.
clearpools()
- gcResetMarkState()
-
work.finalizersDone = false
if mode == gcBackgroundMode { // Do as much work concurrently as possible
@@ -1723,8 +1724,10 @@ func gcCopySpans() {
}
// gcResetMarkState resets global state prior to marking (concurrent
-// or STW) and resets the stack scan state of all Gs. Any Gs created
-// after this will also be in the reset state.
+// or STW) and resets the stack scan state of all Gs.
+//
+// This is safe to do without the world stopped because any Gs created
+// during or after this will start out in the reset state.
func gcResetMarkState() {
// This may be called during a concurrent phase, so make sure
// allgs doesn't change.