Commit 171204b5 authored by Austin Clements's avatar Austin Clements

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/16359Reviewed-by: default avatarRick Hudson <rlh@golang.org>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 12e23f05
...@@ -1116,6 +1116,27 @@ func gcStart(mode gcMode, forceTrigger bool) { ...@@ -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) { func gc(mode gcMode) {
// If mode == gcBackgroundMode, world is not stopped. // If mode == gcBackgroundMode, world is not stopped.
// If mode != gcBackgroundMode, world is stopped. // If mode != gcBackgroundMode, world is stopped.
...@@ -1468,14 +1489,7 @@ func gcBgMarkWorker(p *p) { ...@@ -1468,14 +1489,7 @@ func gcBgMarkWorker(p *p) {
// If this worker reached a background mark completion // If this worker reached a background mark completion
// point, signal the main GC goroutine. // point, signal the main GC goroutine.
if incnwait == work.nproc && !gcMarkWorkAvailable(nil) { if incnwait == work.nproc && !gcMarkWorkAvailable(nil) {
if gcBlackenPromptly { gcMarkDone()
if work.bgMark1.done == 0 {
throw("completing mark 2, but bgMark1.done == 0")
}
work.bgMark2.complete()
} else {
work.bgMark1.complete()
}
} }
duration := nanotime() - startTime duration := nanotime() - startTime
......
...@@ -409,14 +409,7 @@ retry: ...@@ -409,14 +409,7 @@ retry:
if incnwait == work.nproc && !gcMarkWorkAvailable(nil) { if incnwait == work.nproc && !gcMarkWorkAvailable(nil) {
// This has reached a background completion // This has reached a background completion
// point. // point.
if gcBlackenPromptly { gcMarkDone()
if work.bgMark1.done == 0 {
throw("completing mark 2, but bgMark1.done == 0")
}
work.bgMark2.complete()
} else {
work.bgMark1.complete()
}
completed = true completed = true
} }
duration := nanotime() - startTime duration := nanotime() - startTime
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment