aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/proc.c
diff options
context:
space:
mode:
authorDmitriy Vyukov <dvyukov@google.com>2013-08-13 22:12:02 +0400
committerDmitriy Vyukov <dvyukov@google.com>2013-08-13 22:12:02 +0400
commitcc4e6aad8ec18b4ee7fe0392f30f229ddb979589 (patch)
tree73680a46d29bf17e50838c8ac4e3546780d52699 /src/pkg/runtime/proc.c
parent1da1030b5dd9d9610ccada4413a23e77b21c7f3b (diff)
downloadgo-cc4e6aad8ec18b4ee7fe0392f30f229ddb979589.tar.xz
runtime: do no lose CPU profiling signals
Currently we lose lots of profiling signals. Most notably, GC is not accounted at all. But stack splits, scheduler, syscalls, etc are lost as well. This creates seriously misleading profile. With this change all profiling signals are accounted. Now I see these additional entries that were previously absent: 161 29.7% 29.7% 164 30.3% syscall.Syscall 12 2.2% 50.9% 12 2.2% scanblock 11 2.0% 55.0% 11 2.0% markonly 10 1.8% 58.9% 10 1.8% sweepspan 2 0.4% 85.8% 2 0.4% runtime.newstack It is still impossible to understand what causes stack splits, but at least it's clear how many time is spent on them. Update #2197. Update #5659. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/12179043
Diffstat (limited to 'src/pkg/runtime/proc.c')
-rw-r--r--src/pkg/runtime/proc.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c
index ef4d27f314..10a25f0a95 100644
--- a/src/pkg/runtime/proc.c
+++ b/src/pkg/runtime/proc.c
@@ -1990,26 +1990,45 @@ static struct {
uintptr pcbuf[100];
} prof;
+static void
+System(void)
+{
+}
+
// Called if we receive a SIGPROF signal.
void
runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp)
{
int32 n;
+ bool traceback;
- // Windows does profiling in a dedicated thread w/o m.
- if(!Windows && (m == nil || m->mcache == nil))
- return;
if(prof.fn == nil || prof.hz == 0)
return;
+ traceback = true;
+ // Windows does profiling in a dedicated thread w/o m.
+ if(!Windows && (m == nil || m->mcache == nil))
+ traceback = false;
+ if(gp == m->g0 || gp == m->gsignal)
+ traceback = false;
+ // Race detector calls asmcgocall w/o entersyscall/exitsyscall,
+ // we can not currently unwind through asmcgocall.
+ if(m != nil && m->racecall)
+ traceback = false;
runtime·lock(&prof);
if(prof.fn == nil) {
runtime·unlock(&prof);
return;
}
- n = runtime·gentraceback((uintptr)pc, (uintptr)sp, (uintptr)lr, gp, 0, prof.pcbuf, nelem(prof.pcbuf), nil, nil, false);
- if(n > 0)
- prof.fn(prof.pcbuf, n);
+ n = 0;
+ if(traceback)
+ n = runtime·gentraceback((uintptr)pc, (uintptr)sp, (uintptr)lr, gp, 0, prof.pcbuf, nelem(prof.pcbuf), nil, nil, false);
+ if(!traceback || n <= 0) {
+ n = 2;
+ prof.pcbuf[0] = (uintptr)pc;
+ prof.pcbuf[1] = (uintptr)System + 1;
+ }
+ prof.fn(prof.pcbuf, n);
runtime·unlock(&prof);
}