aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/proc.c
diff options
context:
space:
mode:
authorDmitriy Vyukov <dvyukov@google.com>2014-01-27 23:17:46 +0400
committerDmitriy Vyukov <dvyukov@google.com>2014-01-27 23:17:46 +0400
commit179d41feccc29260d1a16294647df218f1a6746a (patch)
tree356442abe1e2e0850bc2b849437873f776bd0195 /src/pkg/runtime/proc.c
parentea86752206fd8801bce46cc21a0faf97d8d7cd01 (diff)
downloadgo-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/runtime/proc.c')
-rw-r--r--src/pkg/runtime/proc.c9
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.