diff options
| author | Dmitriy Vyukov <dvyukov@google.com> | 2014-01-27 23:17:46 +0400 |
|---|---|---|
| committer | Dmitriy Vyukov <dvyukov@google.com> | 2014-01-27 23:17:46 +0400 |
| commit | 179d41feccc29260d1a16294647df218f1a6746a (patch) | |
| tree | 356442abe1e2e0850bc2b849437873f776bd0195 /src/pkg | |
| parent | ea86752206fd8801bce46cc21a0faf97d8d7cd01 (diff) | |
| download | go-179d41feccc29260d1a16294647df218f1a6746a.tar.xz | |
runtime: tune P retake logic
When GOMAXPROCS>1 the last P in syscall is never retaken
(because there are already idle P's -- npidle>0).
This prevents sysmon thread from sleeping.
On a darwin machine the program from issue 6673 constantly
consumes ~0.2% CPU. With this change it stably consumes 0.0% CPU.
Fixes #6673.
R=golang-codereviews, r
CC=bradfitz, golang-codereviews, iant, khr
https://golang.org/cl/56990045
Diffstat (limited to 'src/pkg')
| -rw-r--r-- | src/pkg/runtime/proc.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c index afe71ef69e..d2db74d541 100644 --- a/src/pkg/runtime/proc.c +++ b/src/pkg/runtime/proc.c @@ -2534,16 +2534,19 @@ retake(int64 now) pd = &pdesc[i]; s = p->status; if(s == Psyscall) { - // Retake P from syscall if it's there for more than 1 sysmon tick (20us). - // But only if there is other work to do. + // Retake P from syscall if it's there for more than 1 sysmon tick (at least 20us). t = p->syscalltick; if(pd->syscalltick != t) { pd->syscalltick = t; pd->syscallwhen = now; continue; } + // On the one hand we don't want to retake Ps if there is no other work to do, + // but on the other hand we want to retake them eventually + // because they can prevent the sysmon thread from deep sleep. if(p->runqhead == p->runqtail && - runtime·atomicload(&runtime·sched.nmspinning) + runtime·atomicload(&runtime·sched.npidle) > 0) + runtime·atomicload(&runtime·sched.nmspinning) + runtime·atomicload(&runtime·sched.npidle) > 0 && + pd->syscallwhen + 10*1000*1000 > now) continue; // Need to decrement number of idle locked M's // (pretending that one more is running) before the CAS. |
