aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pratt <mpratt@google.com>2022-06-28 16:32:50 -0400
committerHeschi Kreinick <heschi@google.com>2022-07-06 20:57:57 +0000
commitae2dfcc1c8891a7610f2d31d457427b71ed9c6e0 (patch)
treee5980a6d656cc066d59af659f58373d3930a7284
parentfc07039e2339a80f53e7db5e214b5be504bc1df6 (diff)
downloadgo-ae2dfcc1c8891a7610f2d31d457427b71ed9c6e0.tar.gz
go-ae2dfcc1c8891a7610f2d31d457427b71ed9c6e0.zip
[release-branch.go1.17] runtime: add race annotations to cbs.lock
cbs.lock protects a map. The map implementation is race instrumented regardless of which package is it called from. lock/unlock are not automatically race instrumented, so we can trigger race false positives without manually annotating our lock acquire and release. compileCallback is used during initialization before the P is available, at which point raceacquire will crash during a racecallback to get the race proc. Thus we skip instrumentation until scheduler initialization is complete. Fixes #53612. For #50249. Change-Id: Ie49227c9e9210ffbf0aee65f86f2b7b6a2f64638 Reviewed-on: https://go-review.googlesource.com/c/go/+/414518 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> Run-TryBot: Michael Pratt <mpratt@google.com> (cherry picked from commit 20760cff001e9acc05627dfeab42ea50b57920e6) Reviewed-on: https://go-review.googlesource.com/c/go/+/415197
-rw-r--r--src/runtime/syscall_windows.go28
1 files changed, 23 insertions, 5 deletions
diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go
index 94a61c8823..30ef72bce9 100644
--- a/src/runtime/syscall_windows.go
+++ b/src/runtime/syscall_windows.go
@@ -12,12 +12,30 @@ import (
// cbs stores all registered Go callbacks.
var cbs struct {
- lock mutex
+ lock mutex // use cbsLock / cbsUnlock for race instrumentation.
ctxt [cb_max]winCallback
index map[winCallbackKey]int
n int
}
+func cbsLock() {
+ lock(&cbs.lock)
+ // compileCallback is used by goenvs prior to completion of schedinit.
+ // raceacquire involves a racecallback to get the proc, which is not
+ // safe prior to scheduler initialization. Thus avoid instrumentation
+ // until then.
+ if raceenabled && mainStarted {
+ raceacquire(unsafe.Pointer(&cbs.lock))
+ }
+}
+
+func cbsUnlock() {
+ if raceenabled && mainStarted {
+ racerelease(unsafe.Pointer(&cbs.lock))
+ }
+ unlock(&cbs.lock)
+}
+
// winCallback records information about a registered Go callback.
type winCallback struct {
fn *funcval // Go function
@@ -302,11 +320,11 @@ func compileCallback(fn eface, cdecl bool) (code uintptr) {
key := winCallbackKey{(*funcval)(fn.data), cdecl}
- lock(&cbs.lock) // We don't unlock this in a defer because this is used from the system stack.
+ cbsLock()
// Check if this callback is already registered.
if n, ok := cbs.index[key]; ok {
- unlock(&cbs.lock)
+ cbsUnlock()
return callbackasmAddr(n)
}
@@ -316,7 +334,7 @@ func compileCallback(fn eface, cdecl bool) (code uintptr) {
}
n := cbs.n
if n >= len(cbs.ctxt) {
- unlock(&cbs.lock)
+ cbsUnlock()
throw("too many callback functions")
}
c := winCallback{key.fn, retPop, abiMap}
@@ -324,7 +342,7 @@ func compileCallback(fn eface, cdecl bool) (code uintptr) {
cbs.index[key] = n
cbs.n++
- unlock(&cbs.lock)
+ cbsUnlock()
return callbackasmAddr(n)
}