mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: decentralize mark done and mark termination
This moves all of the mark 1 to mark 2 transition and mark termination to the mark done transition function. This means these transitions are now handled on the goroutine that detected mark completion. This also means that the GC coordinator and the background completion barriers are no longer used and various workarounds to yield to the coordinator are no longer necessary. These will be removed in follow-up commits. One consequence of this is that mark workers now need to be preemptible when performing the mark done transition. This allows them to stop the world and to perform the final clean-up steps of GC after restarting the world. They are only made preemptible while performing this transition, so if the worker findRunnableGCWorker would schedule isn't available, we didn't want to schedule it anyway. Fixes #11970. Change-Id: I9203a2d6287eeff62d589ec02ad9cb1e29ddb837 Reviewed-on: https://go-review.googlesource.com/16391 Reviewed-by: Rick Hudson <rlh@golang.org> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
d986bf2741
commit
c99d7f7f85
4 changed files with 121 additions and 77 deletions
|
|
@ -1057,6 +1057,8 @@ func mstart1() {
|
|||
// memory barrier. GC uses this as a "ragged barrier."
|
||||
//
|
||||
// The caller must hold worldsema.
|
||||
//
|
||||
//go:systemstack
|
||||
func forEachP(fn func(*p)) {
|
||||
mp := acquirem()
|
||||
_p_ := getg().m.p.ptr()
|
||||
|
|
@ -1115,6 +1117,8 @@ func forEachP(fn func(*p)) {
|
|||
for {
|
||||
// Wait for 100us, then try to re-preempt in
|
||||
// case of any races.
|
||||
//
|
||||
// Requires system stack.
|
||||
if notetsleep(&sched.safePointNote, 100*1000) {
|
||||
noteclear(&sched.safePointNote)
|
||||
break
|
||||
|
|
@ -1773,10 +1777,9 @@ top:
|
|||
stop:
|
||||
|
||||
// We have nothing to do. If we're in the GC mark phase, can
|
||||
// safely scan and blacken objects, can start a worker, and
|
||||
// have work to do, run idle-time marking rather than give up
|
||||
// the P.
|
||||
if _p_ := _g_.m.p.ptr(); gcBlackenEnabled != 0 && _p_.gcBgMarkWorker != nil && (work.bgMark1.done == 0 || work.bgMark2.done == 0) && gcMarkWorkAvailable(_p_) {
|
||||
// safely scan and blacken objects, and have work to do, run
|
||||
// idle-time marking rather than give up the P.
|
||||
if _p_ := _g_.m.p.ptr(); gcBlackenEnabled != 0 && _p_.gcBgMarkWorker != nil && gcMarkWorkAvailable(_p_) {
|
||||
_p_.gcMarkWorkerMode = gcMarkWorkerIdleMode
|
||||
gp := _p_.gcBgMarkWorker
|
||||
casgstatus(gp, _Gwaiting, _Grunnable)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue