From: Austin Clements Date: Sun, 25 Oct 2015 01:30:59 +0000 (-0400) Subject: runtime: factor mark done transition X-Git-Tag: go1.6beta1~615 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=171204b5617b317250d54bd45750476f69ee33d8;p=gostls13.git runtime: factor mark done transition Currently the code for completion of mark 1/mark 2 is duplicated in background workers and assists. Factor this in to a single function that will serve as the transition function for concurrent mark. Change-Id: I4d9f697a15da0d349db3b34d56f3a220dd41d41b Reviewed-on: https://go-review.googlesource.com/16359 Reviewed-by: Rick Hudson Run-TryBot: Austin Clements TryBot-Result: Gobot Gobot --- diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go index 4d75d635d6..5db5941228 100644 --- a/src/runtime/mgc.go +++ b/src/runtime/mgc.go @@ -1116,6 +1116,27 @@ func gcStart(mode gcMode, forceTrigger bool) { } } +// gcMarkDone transitions the GC from mark 1 to mark 2 and from mark 2 +// to mark termination. +// +// This should be called when all mark work has been drained. In mark +// 1, this includes all root marking jobs, global work buffers, and +// active work buffers in assists and background workers; however, +// work may still be cached in per-P work buffers. In mark 2, per-P +// caches are disabled. +func gcMarkDone() { + // TODO(austin): This should perform the transition rather + // than handing it off to the coordinator. + if gcBlackenPromptly { + if work.bgMark1.done == 0 { + throw("completing mark 2, but bgMark1.done == 0") + } + work.bgMark2.complete() + } else { + work.bgMark1.complete() + } +} + func gc(mode gcMode) { // If mode == gcBackgroundMode, world is not stopped. // If mode != gcBackgroundMode, world is stopped. @@ -1468,14 +1489,7 @@ func gcBgMarkWorker(p *p) { // If this worker reached a background mark completion // point, signal the main GC goroutine. if incnwait == work.nproc && !gcMarkWorkAvailable(nil) { - if gcBlackenPromptly { - if work.bgMark1.done == 0 { - throw("completing mark 2, but bgMark1.done == 0") - } - work.bgMark2.complete() - } else { - work.bgMark1.complete() - } + gcMarkDone() } duration := nanotime() - startTime diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go index 0f1359669e..fd969da317 100644 --- a/src/runtime/mgcmark.go +++ b/src/runtime/mgcmark.go @@ -409,14 +409,7 @@ retry: if incnwait == work.nproc && !gcMarkWorkAvailable(nil) { // This has reached a background completion // point. - if gcBlackenPromptly { - if work.bgMark1.done == 0 { - throw("completing mark 2, but bgMark1.done == 0") - } - work.bgMark2.complete() - } else { - work.bgMark1.complete() - } + gcMarkDone() completed = true } duration := nanotime() - startTime