aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2011-10-06 11:30:48 -0400
committerRuss Cox <rsc@golang.org>2011-10-06 11:30:48 -0400
commitad35cea7622a6fb839f06bb5b46cee9110fa94a0 (patch)
tree0472a0afaf739f32faa843d93f90a62f6e843ed3 /src/pkg/runtime
parent56959158331072ed17801aa539a0d6f28064b511 (diff)
downloadgo-ad35cea7622a6fb839f06bb5b46cee9110fa94a0.tar.xz
runtime: fix malloc sampling bug
The malloc sample trigger was not being set in a new m, so the first allocation in each new m - the goroutine structure - was being sampled with probability 1 instead of probability sizeof(G)/rate, an oversampling of about 5000x for the default rate of 1 MB. This bug made pprof graphs show far more G allocations than there actually were. R=golang-dev, r CC=golang-dev https://golang.org/cl/5224041
Diffstat (limited to 'src/pkg/runtime')
-rw-r--r--src/pkg/runtime/malloc.goc9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/pkg/runtime/malloc.goc b/src/pkg/runtime/malloc.goc
index 84e0ac4795..6d2f65b3c9 100644
--- a/src/pkg/runtime/malloc.goc
+++ b/src/pkg/runtime/malloc.goc
@@ -80,6 +80,7 @@ runtime·mallocgc(uintptr size, uint32 flag, int32 dogc, int32 zeroed)
m->mcache->next_sample -= size;
else {
// pick next profile time
+ // If you change this, also change allocmcache.
if(rate > 0x3fffffff) // make 2*rate not overflow
rate = 0x3fffffff;
m->mcache->next_sample = runtime·fastrand1() % (2*rate);
@@ -205,6 +206,7 @@ runtime·mlookup(void *v, byte **base, uintptr *size, MSpan **sp)
MCache*
runtime·allocmcache(void)
{
+ int32 rate;
MCache *c;
runtime·lock(&runtime·mheap);
@@ -212,6 +214,13 @@ runtime·allocmcache(void)
mstats.mcache_inuse = runtime·mheap.cachealloc.inuse;
mstats.mcache_sys = runtime·mheap.cachealloc.sys;
runtime·unlock(&runtime·mheap);
+
+ // Set first allocation sample size.
+ rate = runtime·MemProfileRate;
+ if(rate > 0x3fffffff) // make 2*rate not overflow
+ rate = 0x3fffffff;
+ c->next_sample = runtime·fastrand1() % (2*rate);
+
return c;
}