]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: refactor CPU profiling
authorDmitriy Vyukov <dvyukov@google.com>
Mon, 25 Aug 2014 08:10:24 +0000 (12:10 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Mon, 25 Aug 2014 08:10:24 +0000 (12:10 +0400)
Reduce duration of critical section,
make pcbuf local to function.

LGTM=rsc
R=golang-codereviews
CC=golang-codereviews, rsc
https://golang.org/cl/102600043

src/pkg/runtime/proc.c

index 44757a8afd28e170255476671dbad1b0ebd58101..31ff4f55def475401bf83e10aa5726ea038081a6 100644 (file)
@@ -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--;
 }