mirror of
https://github.com/golang/go
synced 2024-11-23 14:40:02 -07:00
runtime: use current P's race context in timer code
We were using the race context of the P that held the timer, but since we unlock the P's timers while executing a timer that could lead to a race on the race context itself. Updates #6239 Updates #27707 Fixes #35906 Change-Id: I5f9d5f52d8e28dffb88c3327301071b16ed1a913 Reviewed-on: https://go-review.googlesource.com/c/go/+/209580 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
parent
a18608a044
commit
94f4686a77
33
src/runtime/race/timer_test.go
Normal file
33
src/runtime/race/timer_test.go
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build race
|
||||
|
||||
package race_test
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestTimers(t *testing.T) {
|
||||
const goroutines = 8
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(goroutines)
|
||||
var mu sync.Mutex
|
||||
for i := 0; i < goroutines; i++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
ticker := time.NewTicker(1)
|
||||
defer ticker.Stop()
|
||||
for c := 0; c < 1000; c++ {
|
||||
<-ticker.C
|
||||
mu.Lock()
|
||||
mu.Unlock()
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
@ -805,10 +805,11 @@ func runtimer(pp *p, now int64) int64 {
|
||||
//go:systemstack
|
||||
func runOneTimer(pp *p, t *timer, now int64) {
|
||||
if raceenabled {
|
||||
if pp.timerRaceCtx == 0 {
|
||||
pp.timerRaceCtx = racegostart(funcPC(runtimer) + sys.PCQuantum)
|
||||
ppcur := getg().m.p.ptr()
|
||||
if ppcur.timerRaceCtx == 0 {
|
||||
ppcur.timerRaceCtx = racegostart(funcPC(runtimer) + sys.PCQuantum)
|
||||
}
|
||||
raceacquirectx(pp.timerRaceCtx, unsafe.Pointer(t))
|
||||
raceacquirectx(ppcur.timerRaceCtx, unsafe.Pointer(t))
|
||||
}
|
||||
|
||||
f := t.f
|
||||
@ -836,12 +837,12 @@ func runOneTimer(pp *p, t *timer, now int64) {
|
||||
}
|
||||
|
||||
if raceenabled {
|
||||
// Temporarily use the P's racectx for g0.
|
||||
// Temporarily use the current P's racectx for g0.
|
||||
gp := getg()
|
||||
if gp.racectx != 0 {
|
||||
throw("runOneTimer: unexpected racectx")
|
||||
}
|
||||
gp.racectx = pp.timerRaceCtx
|
||||
gp.racectx = gp.m.p.ptr().timerRaceCtx
|
||||
}
|
||||
|
||||
unlock(&pp.timersLock)
|
||||
|
Loading…
Reference in New Issue
Block a user