Skip to content

Commit

Permalink
runtime: recheck GC trigger before actually starting GC
Browse files Browse the repository at this point in the history
Currently allocation checks the GC trigger speculatively during
allocation and then triggers the GC without rechecking. As a result,
it's possible for G 1 and G 2 to detect the trigger simultaneously,
both enter startGC, G 1 actually starts GC while G 2 gets preempted
until after the whole GC cycle, then G 2 immediately starts another GC
cycle even though the heap is now well under the trigger.

Fix this by re-checking the GC trigger non-speculatively just before
actually kicking off a new GC cycle.

This contributes to #11911 because when this happens, we definitely
don't finish the background sweep before starting the next GC cycle,
which can significantly delay the start of concurrent scan.

Change-Id: I560ab79ba5684ba435084410a9765d28f5745976
Reviewed-on: https://go-review.googlesource.com/13025
Reviewed-by: Russ Cox <rsc@golang.org>
Reviewed-by: Rick Hudson <rlh@golang.org>
  • Loading branch information
aclements committed Aug 4, 2015
1 parent d5f5e65 commit 88e945f
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/runtime/mgc.go
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,14 @@ func startGC(mode int) {
// trigger concurrent GC
readied := false
lock(&bggc.lock)
// The trigger was originally checked speculatively, so
// recheck that this really should trigger GC. (For example,
// we may have gone through a whole GC cycle since the
// speculative check.)
if !shouldtriggergc() {
unlock(&bggc.lock)
return
}
if !bggc.started {
bggc.working = 1
bggc.started = true
Expand Down

0 comments on commit 88e945f

Please sign in to comment.