57584a0ee1
Because profile labels are copied from the goroutine into the tag buffer by the signal handler, there's a carefully-crafted set of race detector annotations to create the necessary happens-before edges between setting a goroutine's profile label and retrieving it from the profile tag buffer. Given the constraints of the signal handler, we have to approximate the true synchronization behavior. Currently, that approximation is too weak. Ideally, runtime_setProfLabel would perform a store-release on &getg().labels and copying each label into the profile would perform a load-acquire on &getg().labels. This would create the necessary happens-before edges through each individual g.labels object. Since we can't do this in the signal handler, we instead synchronize on a "labelSync" global. The problem occurs with the following sequence: 1. Goroutine 1 calls setProfLabel, which does a store-release on labelSync. 2. Goroutine 2 calls setProfLabel, which does a store-release on labelSync. 3. Goroutine 3 reads the profile, which does a load-acquire on labelSync. The problem is that the load-acquire only synchronizes with the *most recent* store-release to labelSync, and the two store-releases don't synchronize with each other. So, once goroutine 3 touches the label set by goroutine 1, we report a race. The solution is to use racereleasemerge. This is like a read-modify-write, rather than just a store-release. Each RMW of labelSync in runtime_setProfLabel synchronizes with the previous RMW of labelSync, and this ultimately carries forward to the load-acquire, so it synchronizes with *all* setProfLabel operations, not just the most recent. Change-Id: Iab58329b156122002fff12cfe64fbeacb31c9613 Reviewed-on: https://go-review.googlesource.com/56670 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Russ Cox <rsc@golang.org> Reviewed-by: Dmitry Vyukov <dvyukov@google.com> |
||
---|---|---|
.github | ||
api | ||
doc | ||
lib/time | ||
misc | ||
src | ||
test | ||
.gitattributes | ||
.gitignore | ||
AUTHORS | ||
CONTRIBUTING.md | ||
CONTRIBUTORS | ||
favicon.ico | ||
LICENSE | ||
PATENTS | ||
README.md | ||
robots.txt |
The Go Programming Language
Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.
Gopher image by Renee French, licensed under Creative Commons 3.0 Attributions license.
Our canonical Git repository is located at https://go.googlesource.com/go. There is a mirror of the repository at https://github.com/golang/go.
Unless otherwise noted, the Go source files are distributed under the BSD-style license found in the LICENSE file.
Download and Install
Binary Distributions
Official binary distributions are available at https://golang.org/dl/.
After downloading a binary release, visit https://golang.org/doc/install or load doc/install.html in your web browser for installation instructions.
Install From Source
If a binary distribution is not available for your combination of operating system and architecture, visit https://golang.org/doc/install/source or load doc/install-source.html in your web browser for source installation instructions.
Contributing
Go is the work of hundreds of contributors. We appreciate your help!
To contribute, please read the contribution guidelines: https://golang.org/doc/contribute.html
Note that the Go project does not use GitHub pull requests, and that we use the issue tracker for bug reports and proposals only. See https://golang.org/wiki/Questions for a list of places to ask questions about the Go language.