aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/metrics.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/metrics.go')
-rw-r--r--src/runtime/metrics.go45
1 files changed, 31 insertions, 14 deletions
diff --git a/src/runtime/metrics.go b/src/runtime/metrics.go
index ba0a920a5d..922dd2f814 100644
--- a/src/runtime/metrics.go
+++ b/src/runtime/metrics.go
@@ -12,9 +12,12 @@ import (
)
var (
- // metrics is a map of runtime/metrics keys to
- // data used by the runtime to sample each metric's
- // value.
+ // metrics is a map of runtime/metrics keys to data used by the runtime
+ // to sample each metric's value. metricsInit indicates it has been
+ // initialized.
+ //
+ // These fields are protected by metricsSema which should be
+ // locked/unlocked with metricsLock() / metricsUnlock().
metricsSema uint32 = 1
metricsInit bool
metrics map[string]metricData
@@ -34,6 +37,23 @@ type metricData struct {
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.
//
// metricsSema must be held.
@@ -388,13 +408,13 @@ func (a *heapStatsAggregate) compute() {
memstats.heapStats.read(&a.heapStatsDelta)
// Calculate derived stats.
- a.totalAllocs = uint64(a.largeAllocCount)
- a.totalFrees = uint64(a.largeFreeCount)
- a.totalAllocated = uint64(a.largeAlloc)
- a.totalFreed = uint64(a.largeFree)
+ a.totalAllocs = a.largeAllocCount
+ a.totalFrees = a.largeFreeCount
+ a.totalAllocated = a.largeAlloc
+ a.totalFreed = a.largeFree
for i := range a.smallAllocCount {
- na := uint64(a.smallAllocCount[i])
- nf := uint64(a.smallFreeCount[i])
+ na := a.smallAllocCount[i]
+ nf := a.smallFreeCount[i]
a.totalAllocs += na
a.totalFrees += nf
a.totalAllocated += na * uint64(class_to_size[i])
@@ -546,10 +566,7 @@ func readMetrics(samplesp unsafe.Pointer, len int, cap int) {
sl := slice{samplesp, len, cap}
samples := *(*[]metricSample)(unsafe.Pointer(&sl))
- // Acquire the metricsSema but with handoff. This operation
- // is expensive enough that queueing up goroutines and handing
- // off between them will be noticeably better-behaved.
- semacquire1(&metricsSema, true, 0, 0)
+ metricsLock()
// Ensure the map is initialized.
initMetrics()
@@ -573,5 +590,5 @@ func readMetrics(samplesp unsafe.Pointer, len int, cap int) {
data.compute(&agg, &sample.value)
}
- semrelease(&metricsSema)
+ metricsUnlock()
}