mirror of
https://github.com/golang/go.git
synced 2025-05-05 23:53:05 +00:00
[release-branch.go1.17] runtime: add race annotations to metricsSema
metricsSema protects the metrics map. The map implementation is race instrumented regardless of which package is it called from. semacquire/semrelease are not automatically race instrumented, so we can trigger race false positives without manually annotating our lock acquire and release. See similar instrumentation on trace.shutdownSema and reflectOffs.lock. Fixes #53589. For #53542. Change-Id: Ia3fd239ac860e037d09c7cb9c4ad267391e70705 Reviewed-on: https://go-review.googlesource.com/c/go/+/414517 Run-TryBot: Michael Pratt <mpratt@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> (cherry picked from commit d6481d5b9662b29453004204746945a93a6b4eb2) Reviewed-on: https://go-review.googlesource.com/c/go/+/415196
This commit is contained in:
parent
9ef614f5aa
commit
fc07039e23
@ -321,9 +321,9 @@ func ReadMetricsSlow(memStats *MemStats, samplesp unsafe.Pointer, len, cap int)
|
|||||||
|
|
||||||
// Initialize the metrics beforehand because this could
|
// Initialize the metrics beforehand because this could
|
||||||
// allocate and skew the stats.
|
// allocate and skew the stats.
|
||||||
semacquire(&metricsSema)
|
metricsLock()
|
||||||
initMetrics()
|
initMetrics()
|
||||||
semrelease(&metricsSema)
|
metricsUnlock()
|
||||||
|
|
||||||
systemstack(func() {
|
systemstack(func() {
|
||||||
// Read memstats first. It's going to flush
|
// Read memstats first. It's going to flush
|
||||||
|
@ -12,9 +12,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// metrics is a map of runtime/metrics keys to
|
// metrics is a map of runtime/metrics keys to data used by the runtime
|
||||||
// data used by the runtime to sample each metric's
|
// to sample each metric's value. metricsInit indicates it has been
|
||||||
// value.
|
// initialized.
|
||||||
|
//
|
||||||
|
// These fields are protected by metricsSema which should be
|
||||||
|
// locked/unlocked with metricsLock() / metricsUnlock().
|
||||||
metricsSema uint32 = 1
|
metricsSema uint32 = 1
|
||||||
metricsInit bool
|
metricsInit bool
|
||||||
metrics map[string]metricData
|
metrics map[string]metricData
|
||||||
@ -34,6 +37,23 @@ type metricData struct {
|
|||||||
compute func(in *statAggregate, out *metricValue)
|
compute func(in *statAggregate, out *metricValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func metricsLock() {
|
||||||
|
// Acquire the metricsSema but with handoff. Operations are typically
|
||||||
|
// expensive enough that queueing up goroutines and handing off between
|
||||||
|
// them will be noticeably better-behaved.
|
||||||
|
semacquire1(&metricsSema, true, 0, 0)
|
||||||
|
if raceenabled {
|
||||||
|
raceacquire(unsafe.Pointer(&metricsSema))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func metricsUnlock() {
|
||||||
|
if raceenabled {
|
||||||
|
racerelease(unsafe.Pointer(&metricsSema))
|
||||||
|
}
|
||||||
|
semrelease(&metricsSema)
|
||||||
|
}
|
||||||
|
|
||||||
// initMetrics initializes the metrics map if it hasn't been yet.
|
// initMetrics initializes the metrics map if it hasn't been yet.
|
||||||
//
|
//
|
||||||
// metricsSema must be held.
|
// metricsSema must be held.
|
||||||
@ -546,10 +566,7 @@ func readMetrics(samplesp unsafe.Pointer, len int, cap int) {
|
|||||||
sl := slice{samplesp, len, cap}
|
sl := slice{samplesp, len, cap}
|
||||||
samples := *(*[]metricSample)(unsafe.Pointer(&sl))
|
samples := *(*[]metricSample)(unsafe.Pointer(&sl))
|
||||||
|
|
||||||
// Acquire the metricsSema but with handoff. This operation
|
metricsLock()
|
||||||
// is expensive enough that queueing up goroutines and handing
|
|
||||||
// off between them will be noticeably better-behaved.
|
|
||||||
semacquire1(&metricsSema, true, 0, 0)
|
|
||||||
|
|
||||||
// Ensure the map is initialized.
|
// Ensure the map is initialized.
|
||||||
initMetrics()
|
initMetrics()
|
||||||
@ -573,5 +590,5 @@ func readMetrics(samplesp unsafe.Pointer, len int, cap int) {
|
|||||||
data.compute(&agg, &sample.value)
|
data.compute(&agg, &sample.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
semrelease(&metricsSema)
|
metricsUnlock()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user