aboutsummaryrefslogtreecommitdiff
path: root/src/pkg
diff options
context:
space:
mode:
authorDmitriy Vyukov <dvyukov@google.com>2014-08-25 12:10:24 +0400
committerDmitriy Vyukov <dvyukov@google.com>2014-08-25 12:10:24 +0400
commitf595f834be92ee726ddfb0bea223243ebba32eac (patch)
tree2a7bbda26415cc619089b6870aea2c0565a4c508 /src/pkg
parent7b3677bf3c02f79dc51575ef7b05ea2f4372df90 (diff)
downloadgo-f595f834be92ee726ddfb0bea223243ebba32eac.tar.xz
runtime: refactor CPU profiling
Reduce duration of critical section, make pcbuf local to function. LGTM=rsc R=golang-codereviews CC=golang-codereviews, rsc https://golang.org/cl/102600043
Diffstat (limited to 'src/pkg')
-rw-r--r--src/pkg/runtime/proc.c29
1 files changed, 14 insertions, 15 deletions
diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c
index 44757a8afd..31ff4f55de 100644
--- a/src/pkg/runtime/proc.c
+++ b/src/pkg/runtime/proc.c
@@ -2253,7 +2253,6 @@ static struct {
Lock lock;
void (*fn)(uintptr*, int32);
int32 hz;
- uintptr pcbuf[100];
} prof;
static void System(void) {}
@@ -2270,6 +2269,7 @@ runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp, M *mp)
// Do not use global m in this function, use mp instead.
// On windows one m is sending reports about all the g's, so m means a wrong thing.
byte m;
+ uintptr stk[100];
m = 0;
USED(m);
@@ -2358,15 +2358,9 @@ runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp, M *mp)
((uint8*)runtime·gogo <= pc && pc < (uint8*)runtime·gogo + RuntimeGogoBytes))
traceback = false;
- runtime·lock(&prof.lock);
- if(prof.fn == nil) {
- runtime·unlock(&prof.lock);
- mp->mallocing--;
- return;
- }
n = 0;
if(traceback)
- n = runtime·gentraceback((uintptr)pc, (uintptr)sp, (uintptr)lr, gp, 0, prof.pcbuf, nelem(prof.pcbuf), nil, nil, false);
+ n = runtime·gentraceback((uintptr)pc, (uintptr)sp, (uintptr)lr, gp, 0, stk, nelem(stk), nil, nil, false);
if(!traceback || n <= 0) {
// Normal traceback is impossible or has failed.
// See if it falls into several common cases.
@@ -2376,13 +2370,13 @@ runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp, M *mp)
// Cgo, we can't unwind and symbolize arbitrary C code,
// so instead collect Go stack that leads to the cgo call.
// This is especially important on windows, since all syscalls are cgo calls.
- n = runtime·gentraceback(mp->curg->syscallpc, mp->curg->syscallsp, 0, mp->curg, 0, prof.pcbuf, nelem(prof.pcbuf), nil, nil, false);
+ n = runtime·gentraceback(mp->curg->syscallpc, mp->curg->syscallsp, 0, mp->curg, 0, stk, nelem(stk), nil, nil, false);
}
#ifdef GOOS_windows
if(n == 0 && mp->libcallg != nil && mp->libcallpc != 0 && mp->libcallsp != 0) {
// Libcall, i.e. runtime syscall on windows.
// Collect Go stack that leads to the call.
- n = runtime·gentraceback(mp->libcallpc, mp->libcallsp, 0, mp->libcallg, 0, prof.pcbuf, nelem(prof.pcbuf), nil, nil, false);
+ n = runtime·gentraceback(mp->libcallpc, mp->libcallsp, 0, mp->libcallg, 0, stk, nelem(stk), nil, nil, false);
}
#endif
if(n == 0) {
@@ -2391,15 +2385,20 @@ runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp, M *mp)
// "ExternalCode" is better than "etext".
if((uintptr)pc > (uintptr)etext)
pc = (byte*)ExternalCode + PCQuantum;
- prof.pcbuf[0] = (uintptr)pc;
+ stk[0] = (uintptr)pc;
if(mp->gcing || mp->helpgc)
- prof.pcbuf[1] = (uintptr)GC + PCQuantum;
+ stk[1] = (uintptr)GC + PCQuantum;
else
- prof.pcbuf[1] = (uintptr)System + PCQuantum;
+ stk[1] = (uintptr)System + PCQuantum;
}
}
- prof.fn(prof.pcbuf, n);
- runtime·unlock(&prof.lock);
+
+ if(prof.fn != nil) {
+ runtime·lock(&prof.lock);
+ if(prof.fn != nil)
+ prof.fn(stk, n);
+ runtime·unlock(&prof.lock);
+ }
mp->mallocing--;
}