1
0
mirror of https://github.com/golang/go synced 2024-11-19 09:04:41 -07:00

runtime: run concurrent mark phase on regular stack

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>
This commit is contained in:
Austin Clements 2015-03-18 11:22:12 -04:00
parent bef356b282
commit fa2f9c2c09

View File

@ -339,18 +339,18 @@ func gc(mode int) {
// Concurrent mark. // Concurrent mark.
starttheworld() 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 { } else {
// For non-concurrent GC (mode != gcBackgroundMode) // For non-concurrent GC (mode != gcBackgroundMode)
// The g stacks have not been scanned so clear g state // The g stacks have not been scanned so clear g state