1
0
mirror of https://github.com/golang/go synced 2024-11-23 19:30:05 -07:00

runtime: avoid double-scanning of stacks

Currently there's a race between stopg scanning another G's stack and
the G reaching a preemption point and scanning its own stack. When
this race occurs, the G's stack is scanned twice. Currently this is
okay, so this race is benign.

However, we will shortly be adding stack barriers during the first
stack scan, so scanning will no longer be idempotent. To prepare for
this, this change ensures that each stack is scanned only once during
each GC phase by checking the flag that indicates that the stack has
been scanned in this phase before scanning the stack.

Change-Id: Id9f4d5e2e5b839bc3f200ec1723a4a12dd677ab4
Reviewed-on: https://go-review.googlesource.com/10458
Reviewed-by: Rick Hudson <rlh@golang.org>
This commit is contained in:
Austin Clements 2015-05-28 12:37:12 -04:00
parent 3f6e69aca5
commit 724f8298a8
2 changed files with 8 additions and 2 deletions

View File

@ -258,6 +258,9 @@ func gcAssistAlloc(size uintptr, allowAssist bool) {
// work is done here.
//go:nowritebarrier
func gcphasework(gp *g) {
if gp.gcworkdone {
return
}
switch gcphase {
default:
throw("gcphasework in bad gcphase")

View File

@ -743,8 +743,11 @@ func newstack() {
}
if gp.preemptscan {
for !castogscanstatus(gp, _Gwaiting, _Gscanwaiting) {
// Likely to be racing with the GC as it sees a _Gwaiting and does the stack scan.
// If so this stack will be scanned twice which does not change correctness.
// Likely to be racing with the GC as
// it sees a _Gwaiting and does the
// stack scan. If so, gcworkdone will
// be set and gcphasework will simply
// return.
}
gcphasework(gp)
casfrom_Gscanstatus(gp, _Gscanwaiting, _Gwaiting)