print(" wbuf2.n=", gcw.wbuf2.nobj)
}
print("\n")
+ if gcw.pauseGen == gcw.putGen {
+ println("runtime: checkPut already failed at this generation")
+ }
throw("throwOnGCWork")
}
}
// gcWorkPauseGen if debugCachedWork is true.
pauseGen uint32
+ // putGen is the pauseGen of the last putGen.
+ putGen uint32
+
// pauseStack is the stack at which this P was paused if
// debugCachedWork is true.
pauseStack [16]uintptr
func (w *gcWork) checkPut(ptr uintptr, ptrs []uintptr) {
if debugCachedWork {
+ alreadyFailed := w.putGen == w.pauseGen
+ w.putGen = w.pauseGen
+ if m := getg().m; m.locks > 0 || m.mallocing != 0 || m.preemptoff != "" || m.p.ptr().status != _Prunning {
+ // If we were to spin, the runtime may
+ // deadlock: the condition above prevents
+ // preemption (see newstack), which could
+ // prevent gcMarkDone from finishing the
+ // ragged barrier and releasing the spin.
+ return
+ }
for atomic.Load(&gcWorkPauseGen) == w.pauseGen {
}
if throwOnGCWork {
printlock()
+ if alreadyFailed {
+ println("runtime: checkPut already failed at this generation")
+ }
println("runtime: late gcWork put")
if ptr != 0 {
gcDumpObject("ptr", ptr, ^uintptr(0))