Commit f595f834 authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

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
parent 7b3677bf
...@@ -2253,7 +2253,6 @@ static struct { ...@@ -2253,7 +2253,6 @@ static struct {
Lock lock; Lock lock;
void (*fn)(uintptr*, int32); void (*fn)(uintptr*, int32);
int32 hz; int32 hz;
uintptr pcbuf[100];
} prof; } prof;
static void System(void) {} static void System(void) {}
...@@ -2270,6 +2269,7 @@ runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp, M *mp) ...@@ -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. // 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. // On windows one m is sending reports about all the g's, so m means a wrong thing.
byte m; byte m;
uintptr stk[100];
m = 0; m = 0;
USED(m); USED(m);
...@@ -2358,15 +2358,9 @@ runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp, M *mp) ...@@ -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)) ((uint8*)runtime·gogo <= pc && pc < (uint8*)runtime·gogo + RuntimeGogoBytes))
traceback = false; traceback = false;
runtime·lock(&prof.lock);
if(prof.fn == nil) {
runtime·unlock(&prof.lock);
mp->mallocing--;
return;
}
n = 0; n = 0;
if(traceback) 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) { if(!traceback || n <= 0) {
// Normal traceback is impossible or has failed. // Normal traceback is impossible or has failed.
// See if it falls into several common cases. // See if it falls into several common cases.
...@@ -2376,13 +2370,13 @@ runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp, M *mp) ...@@ -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, // Cgo, we can't unwind and symbolize arbitrary C code,
// so instead collect Go stack that leads to the cgo call. // so instead collect Go stack that leads to the cgo call.
// This is especially important on windows, since all syscalls are cgo calls. // 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 #ifdef GOOS_windows
if(n == 0 && mp->libcallg != nil && mp->libcallpc != 0 && mp->libcallsp != 0) { if(n == 0 && mp->libcallg != nil && mp->libcallpc != 0 && mp->libcallsp != 0) {
// Libcall, i.e. runtime syscall on windows. // Libcall, i.e. runtime syscall on windows.
// Collect Go stack that leads to the call. // 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 #endif
if(n == 0) { if(n == 0) {
...@@ -2391,15 +2385,20 @@ runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp, M *mp) ...@@ -2391,15 +2385,20 @@ runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp, M *mp)
// "ExternalCode" is better than "etext". // "ExternalCode" is better than "etext".
if((uintptr)pc > (uintptr)etext) if((uintptr)pc > (uintptr)etext)
pc = (byte*)ExternalCode + PCQuantum; pc = (byte*)ExternalCode + PCQuantum;
prof.pcbuf[0] = (uintptr)pc; stk[0] = (uintptr)pc;
if(mp->gcing || mp->helpgc) if(mp->gcing || mp->helpgc)
prof.pcbuf[1] = (uintptr)GC + PCQuantum; stk[1] = (uintptr)GC + PCQuantum;
else 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--; mp->mallocing--;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment