src/runtime/mgc.go | 22 +++++++++++++++++++--- diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go index 22e8c313176eac8fed9b7ab39d45db83eec47a37..705fe697bb449551d448b75ba7989945ae7d02e8 100644 --- a/src/runtime/mgc.go +++ b/src/runtime/mgc.go @@ -688,9 +688,6 @@ if decIfPositive(&c.dedicatedMarkWorkersNeeded) { // This P is now dedicated to marking until the end of // the concurrent mark phase. _p_.gcMarkWorkerMode = gcMarkWorkerDedicatedMode - // TODO(austin): This P isn't going to run anything - // else for a while, so kick everything out of its run - // queue. } else { if !decIfPositive(&c.fractionalMarkWorkersNeeded) { // No more workers are need right now. @@ -1773,6 +1770,25 @@ switch _p_.gcMarkWorkerMode { default: throw("gcBgMarkWorker: unexpected gcMarkWorkerMode") case gcMarkWorkerDedicatedMode: + gcDrain(&_p_.gcw, gcDrainUntilPreempt|gcDrainFlushBgCredit) + if gp.preempt { + // We were preempted. This is + // a useful signal to kick + // everything out of the run + // queue so it can run + // somewhere else. + lock(&sched.lock) + for { + gp, _ := runqget(_p_) + if gp == nil { + break + } + globrunqput(gp) + } + unlock(&sched.lock) + } + // Go back to draining, this time + // without preemption. gcDrain(&_p_.gcw, gcDrainNoBlock|gcDrainFlushBgCredit) case gcMarkWorkerFractionalMode: gcDrain(&_p_.gcw, gcDrainUntilPreempt|gcDrainFlushBgCredit)