aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2017-05-11 15:28:39 -0400
committerChris Broadfoot <cbro@golang.org>2017-05-23 19:42:13 +0000
commit18a13d373a0554a28835c58d1ddfb69b387f41bf (patch)
tree5c8eb775b62f122bad61180ea6f085dfc432c8d3
parent6efa2f22ac45e9f12eccdc0eafe1799b9eb78dd3 (diff)
downloadgo-18a13d373a0554a28835c58d1ddfb69b387f41bf.tar.gz
go-18a13d373a0554a28835c58d1ddfb69b387f41bf.zip
[release-branch.go1.8] runtime: doubly fix "double wakeup" panic
Cherry-pick of CL 43311. runtime.gchelper depends on the non-atomic load of work.ndone happening strictly before the atomic add of work.nwait. Until very recently (commit 978af9c2db, 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 978af9c2db fixed it). Change-Id: Ieb1a84e1e5044c33ac612c8a5ab6297e7db4c57d Reviewed-on: https://go-review.googlesource.com/43412 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
-rw-r--r--src/runtime/mgc.go2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go
index cd57720917..8f424926cb 100644
--- a/src/runtime/mgc.go
+++ b/src/runtime/mgc.go
@@ -1918,7 +1918,7 @@ func gchelper() {
traceGCScanDone()
}
- nproc := work.nproc // work.nproc can change right after we increment work.ndone
+ nproc := atomic.Load(&work.nproc) // work.nproc can change right after we increment work.ndone
if atomic.Xadd(&work.ndone, +1) == nproc-1 {
notewakeup(&work.alldone)
}