diff options
| author | Dmitriy Vyukov <dvyukov@google.com> | 2014-08-25 12:10:24 +0400 |
|---|---|---|
| committer | Dmitriy Vyukov <dvyukov@google.com> | 2014-08-25 12:10:24 +0400 |
| commit | f595f834be92ee726ddfb0bea223243ebba32eac (patch) | |
| tree | 2a7bbda26415cc619089b6870aea2c0565a4c508 /src/pkg/runtime | |
| parent | 7b3677bf3c02f79dc51575ef7b05ea2f4372df90 (diff) | |
| download | go-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/runtime')
| -rw-r--r-- | src/pkg/runtime/proc.c | 29 |
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--; } |
