]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: do not cpu profile idle threads on windows
authorDmitriy Vyukov <dvyukov@google.com>
Mon, 10 Feb 2014 11:40:55 +0000 (15:40 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Mon, 10 Feb 2014 11:40:55 +0000 (15:40 +0400)
Currently this leads to a significant skew towards 'etext' entry,
since all idle threads are profiled every tick.
Before:
Total: 66608 samples
   63188  94.9%  94.9%    63188  94.9% etext
     278   0.4%  95.3%      278   0.4% sweepspan
     216   0.3%  95.6%      448   0.7% runtime.mallocgc
     122   0.2%  95.8%      122   0.2% scanblock
     113   0.2%  96.0%      113   0.2% net/textproto.canonicalMIMEHeaderKey
After:
Total: 8008 samples
    3949  49.3%  49.3%     3949  49.3% etext
     231   2.9%  52.2%      231   2.9% scanblock
     211   2.6%  54.8%      211   2.6% runtime.cas64
     182   2.3%  57.1%      408   5.1% runtime.mallocgc
     178   2.2%  59.3%      178   2.2% runtime.atomicload64

LGTM=alex.brainman
R=golang-codereviews, alex.brainman
CC=golang-codereviews
https://golang.org/cl/61250043

src/pkg/runtime/lock_futex.c
src/pkg/runtime/lock_sema.c
src/pkg/runtime/os_windows.c
src/pkg/runtime/proc.c
src/pkg/runtime/runtime.h

index e6e9be92395f9092fde032513787506e5c016df1..c16ac905dd48c6af9769e5d7af1ee19aa1987b18 100644 (file)
@@ -130,8 +130,11 @@ runtime·notesleep(Note *n)
 {
        if(g != m->g0)
                runtime·throw("notesleep not on g0");
-       while(runtime·atomicload((uint32*)&n->key) == 0)
+       while(runtime·atomicload((uint32*)&n->key) == 0) {
+               m->blocked = true;
                runtime·futexsleep((uint32*)&n->key, 0, -1);
+               m->blocked = false;
+       }
 }
 
 #pragma textflag NOSPLIT
@@ -143,8 +146,11 @@ notetsleep(Note *n, int64 ns, int64 deadline, int64 now)
        // does not count against our nosplit stack sequence.
 
        if(ns < 0) {
-               while(runtime·atomicload((uint32*)&n->key) == 0)
+               while(runtime·atomicload((uint32*)&n->key) == 0) {
+                       m->blocked = true;
                        runtime·futexsleep((uint32*)&n->key, 0, -1);
+                       m->blocked = false;
+               }
                return true;
        }
 
@@ -153,7 +159,9 @@ notetsleep(Note *n, int64 ns, int64 deadline, int64 now)
 
        deadline = runtime·nanotime() + ns;
        for(;;) {
+               m->blocked = true;
                runtime·futexsleep((uint32*)&n->key, 0, ns);
+               m->blocked = false;
                if(runtime·atomicload((uint32*)&n->key) != 0)
                        break;
                now = runtime·nanotime();
index f7156105f97e73ecf6742d2e09d35251e5987abe..927bf11f8457318aa3347cd14bc91a72c9e658d0 100644 (file)
@@ -161,7 +161,9 @@ runtime·notesleep(Note *n)
                return;
        }
        // Queued.  Sleep.
+       m->blocked = true;
        runtime·semasleep(-1);
+       m->blocked = false;
 }
 
 #pragma textflag NOSPLIT
@@ -181,18 +183,23 @@ notetsleep(Note *n, int64 ns, int64 deadline, M *mp)
 
        if(ns < 0) {
                // Queued.  Sleep.
+               m->blocked = true;
                runtime·semasleep(-1);
+               m->blocked = false;
                return true;
        }
 
        deadline = runtime·nanotime() + ns;
        for(;;) {
                // Registered.  Sleep.
+               m->blocked = true;
                if(runtime·semasleep(ns) >= 0) {
+                       m->blocked = false;
                        // Acquired semaphore, semawakeup unregistered us.
                        // Done.
                        return true;
                }
+               m->blocked = false;
 
                // Interrupted or timed out.  Still registered.  Semaphore not acquired.
                ns = deadline - runtime·nanotime();
@@ -214,8 +221,10 @@ notetsleep(Note *n, int64 ns, int64 deadline, M *mp)
                } else if(mp == (M*)LOCKED) {
                        // Wakeup happened so semaphore is available.
                        // Grab it to avoid getting out of sync.
+                       m->blocked = true;
                        if(runtime·semasleep(-1) < 0)
                                runtime·throw("runtime: unable to acquire - semaphore out of sync");
+                       m->blocked = false;
                        return true;
                } else
                        runtime·throw("runtime: unexpected waitm - semaphore out of sync");
index aa6360787a7de8189c49e035194d4272029c9aed..d867b0d50e3a32195ea056aca88d838dd354743f 100644 (file)
@@ -426,10 +426,13 @@ runtime·profileloop1(void)
                allm = runtime·atomicloadp(&runtime·allm);
                for(mp = allm; mp != nil; mp = mp->alllink) {
                        thread = runtime·atomicloadp(&mp->thread);
-                       if(thread == nil)
+                       // Do not profile threads blocked on Notes,
+                       // this includes idle worker threads,
+                       // idle timer thread, idle heap scavenger, etc.
+                       if(thread == nil || mp->profilehz == 0 || mp->blocked)
                                continue;
                        runtime·stdcall(runtime·SuspendThread, 1, thread);
-                       if(mp->profilehz != 0)
+                       if(mp->profilehz != 0 && !mp->blocked)
                                profilem(mp);
                        runtime·stdcall(runtime·ResumeThread, 1, thread);
                }
index d2db74d5416a770e8ec17fdaa508f93b9f83bd9c..52aee39ca334332dacbd8840904c93e4ff54427d 100644 (file)
@@ -2690,10 +2690,10 @@ runtime·schedtrace(bool detailed)
                if(lockedg)
                        id3 = lockedg->goid;
                runtime·printf("  M%d: p=%D curg=%D mallocing=%d throwing=%d gcing=%d"
-                       " locks=%d dying=%d helpgc=%d spinning=%d lockedg=%D\n",
+                       " locks=%d dying=%d helpgc=%d spinning=%d blocked=%d lockedg=%D\n",
                        mp->id, id1, id2,
                        mp->mallocing, mp->throwing, mp->gcing, mp->locks, mp->dying, mp->helpgc,
-                       mp->spinning, id3);
+                       mp->spinning, m->blocked, id3);
        }
        runtime·lock(&allglock);
        for(gi = 0; gi < runtime·allglen; gi++) {
index 13fb55454754e943b94a4b361f93557e573235a7..ff6a93aedb6b10917ba3864ceac4104a2ed70abe 100644 (file)
@@ -312,7 +312,8 @@ struct      M
        int32   dying;
        int32   profilehz;
        int32   helpgc;
-       bool    spinning;
+       bool    spinning;       // M is out of work and is actively looking for work
+       bool    blocked;        // M is blocked on a Note
        uint32  fastrand;
        uint64  ncgocall;       // number of cgo calls in total
        int32   ncgo;           // number of cgo calls currently in progress