]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: factor mark done transition
authorAustin Clements <austin@google.com>
Sun, 25 Oct 2015 01:30:59 +0000 (21:30 -0400)
committerAustin Clements <austin@google.com>
Thu, 5 Nov 2015 21:23:42 +0000 (21:23 +0000)
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 <rlh@golang.org>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/runtime/mgc.go
src/runtime/mgcmark.go

index 4d75d635d669fa5629a4705865c744e59ac94763..5db5941228267736d69ed03c39be83c0a65a51cb 100644 (file)
@@ -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
index 0f1359669e93d5e7ec45f4fbe31b4e2d07babea1..fd969da31792d8b1c1b478e2790dcec00ebae835 100644 (file)
@@ -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