Skip to content

Commit 3b5637f

Browse files
committed
runtime: doubly fix "double wakeup" panic
runtime.gchelper depends on the non-atomic load of work.ndone happening strictly before the atomic add of work.nwait. Until very recently (commit 978af9c, fixing #20334), the compiler reordered these operations. This created a race since work.ndone can change as soon as work.nwait is equal to work.ndone. If that happened, more than one gchelper could attempt to wake up the work.alldone note, causing a "double wakeup" panic. This was fixed in the compiler, but to make this code less subtle, make the load of work.ndone atomic. This clearly forces the order of these operations, ensuring the race doesn't happen. Fixes #19305 (though really 978af9c fixed it). Change-Id: Ieb1a84e1e5044c33ac612c8a5ab6297e7db4c57d Reviewed-on: https://go-review.googlesource.com/43311 Run-TryBot: Austin Clements <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent 29e88d5 commit 3b5637f

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

src/runtime/mgc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2105,7 +2105,7 @@ func gchelper() {
21052105
traceGCScanDone()
21062106
}
21072107

2108-
nproc := work.nproc // work.nproc can change right after we increment work.ndone
2108+
nproc := atomic.Load(&work.nproc) // work.nproc can change right after we increment work.ndone
21092109
if atomic.Xadd(&work.ndone, +1) == nproc-1 {
21102110
notewakeup(&work.alldone)
21112111
}

0 commit comments

Comments
 (0)