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

[dev.garbage] runtime: Stop running gs during the GCscan phase.

Ensure that all gs are in a scan state when their stacks are being scanned.

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/179160044
This commit is contained in:
Rick Hudson 2014-11-21 16:46:27 -05:00
parent 8c3f64022a
commit 273507aa8f
3 changed files with 14 additions and 15 deletions

View File

@ -923,14 +923,11 @@ func scanframe(frame *stkframe, unused unsafe.Pointer) bool {
}
func scanstack(gp *g) {
// TODO(rsc): Due to a precedence error, this was never checked in the original C version.
// If you enable the check, the gothrow happens.
/*
if readgstatus(gp)&_Gscan == 0 {
print("runtime: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", readgstatus(gp), "\n")
gothrow("mark - bad status")
}
*/
if readgstatus(gp)&_Gscan == 0 {
print("runtime:scanstack: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", hex(readgstatus(gp)), "\n")
gothrow("scanstack - bad status")
}
switch readgstatus(gp) &^ _Gscan {
default:

View File

@ -316,6 +316,10 @@ func casfrom_Gscanstatus(gp *g, oldval, newval uint32) {
// Check that transition is valid.
switch oldval {
default:
print("runtime: casfrom_Gscanstatus bad oldval gp=", gp, ", oldval=", hex(oldval), ", newval=", hex(newval), "\n")
dumpgstatus(gp)
gothrow("casfrom_Gscanstatus:top gp->status is not in scan state")
case _Gscanrunnable,
_Gscanwaiting,
_Gscanrunning,
@ -417,13 +421,6 @@ func stopg(gp *g) bool {
return false
case _Grunning:
if gcphase == _GCscan {
// Running routines not scanned during
// GCscan phase, we only scan non-running routines.
gp.gcworkdone = true
return false
}
// Claim goroutine, so we aren't racing with a status
// transition away from Grunning.
if !castogscanstatus(gp, _Grunning, _Gscanrunning) {

View File

@ -682,7 +682,12 @@ func newstack() {
gothrow("runtime: g is running but p is not")
}
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.
}
gcphasework(gp)
casfrom_Gscanstatus(gp, _Gscanwaiting, _Gwaiting)
casgstatus(gp, _Gwaiting, _Grunning)
gp.stackguard0 = gp.stack.lo + _StackGuard
gp.preempt = false