mirror of
https://github.com/golang/go
synced 2024-11-23 07:00:05 -07:00
runtime: use racereleasemerge for godebugInc
CL 549796 adds race annotations to godebugInc. It uses racerelease to model a CompareAndSwap. However, a CompareAndSwap is essentially a load and a store. Modeling it as just racerelease makes it not synchronized with other racerelease, i.e. other CAS. For the following execution thread A B load, got nil load, got nil set *inc set *inc racerelease CAS success racerelease CAS fail load raceacquire use *inc (from A) On thread B, the raceacquire synchronizes with the previous racerelease, which is not synchronized with racerelease on thread A, so it doesn't know that the use of *inc on thread B is after the set on thread A, and will report a race. Change it to use racereleasemerge, which synchronizes with previous racerelease and racereleasemerge. So in the case above it knows thread B's CAS is after thread A's. Also remove stale comment that was more relevant when the code used atomic store, where CL 549796 changed to CAS. Updates #64649. Change-Id: I17671090a19c0699fcb4e6481e2abd98ef2e5542 Reviewed-on: https://go-review.googlesource.com/c/go/+/551856 Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
f6509cf5cd
commit
0b56804084
@ -167,13 +167,10 @@ func (g *godebugInc) IncNonDefault() {
|
||||
if newInc == nil {
|
||||
return
|
||||
}
|
||||
// If other goroutines are racing here, no big deal. One will win,
|
||||
// and all the inc functions will be using the same underlying
|
||||
// *godebug.Setting.
|
||||
inc = new(func())
|
||||
*inc = (*newInc)(g.name)
|
||||
if raceenabled {
|
||||
racerelease(unsafe.Pointer(&g.inc))
|
||||
racereleasemerge(unsafe.Pointer(&g.inc))
|
||||
}
|
||||
if !g.inc.CompareAndSwap(nil, inc) {
|
||||
inc = g.inc.Load()
|
||||
|
Loading…
Reference in New Issue
Block a user