]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: run concurrent mark phase on regular stack
authorAustin Clements <austin@google.com>
Wed, 18 Mar 2015 15:22:12 +0000 (11:22 -0400)
committerAustin Clements <austin@google.com>
Thu, 19 Mar 2015 15:55:12 +0000 (15:55 +0000)
Currently, the GC's concurrent mark phase runs on the system
stack. There's no need to do this, and running it this way ties up the
entire M and P running the GC by preventing the scheduler from
preempting the GC even during concurrent mark.

Fix this by running concurrent mark on the regular G stack. It's still
non-preemptible because we also set preemptoff around the whole GC
process, but this moves us closer to making it preemptible.

Change-Id: Ia9f1245e299b8c5c513a4b1e3ef13eaa35ac5e73
Reviewed-on: https://go-review.googlesource.com/7730
Reviewed-by: Rick Hudson <rlh@golang.org>
src/runtime/mgc.go

index d19606bba78c35134584ffe4b31bf30d0cf7c47b..9d9874006708aaf9510087f0415218284d748171 100644 (file)
@@ -339,18 +339,18 @@ func gc(mode int) {
 
                        // Concurrent mark.
                        starttheworld()
-                       gctimer.cycle.mark = nanotime()
-                       var gcw gcWork
-                       gcDrain(&gcw)
-                       gcw.dispose()
-
-                       // Begin mark termination.
-                       gctimer.cycle.markterm = nanotime()
-                       stoptheworld()
-                       // The gcphase is _GCmark, it will transition to _GCmarktermination
-                       // below. The important thing is that the wb remains active until
-                       // all marking is complete. This includes writes made by the GC.
                })
+               gctimer.cycle.mark = nanotime()
+               var gcw gcWork
+               gcDrain(&gcw)
+               gcw.dispose()
+
+               // Begin mark termination.
+               gctimer.cycle.markterm = nanotime()
+               systemstack(stoptheworld)
+               // The gcphase is _GCmark, it will transition to _GCmarktermination
+               // below. The important thing is that the wb remains active until
+               // all marking is complete. This includes writes made by the GC.
        } else {
                // For non-concurrent GC (mode != gcBackgroundMode)
                // The g stacks have not been scanned so clear g state