Commit 179d41fe authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

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
parent ea867522
...@@ -2534,16 +2534,19 @@ retake(int64 now) ...@@ -2534,16 +2534,19 @@ retake(int64 now)
pd = &pdesc[i]; pd = &pdesc[i];
s = p->status; s = p->status;
if(s == Psyscall) { if(s == Psyscall) {
// Retake P from syscall if it's there for more than 1 sysmon tick (20us). // Retake P from syscall if it's there for more than 1 sysmon tick (at least 20us).
// But only if there is other work to do.
t = p->syscalltick; t = p->syscalltick;
if(pd->syscalltick != t) { if(pd->syscalltick != t) {
pd->syscalltick = t; pd->syscalltick = t;
pd->syscallwhen = now; pd->syscallwhen = now;
continue; 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 && 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; continue;
// Need to decrement number of idle locked M's // Need to decrement number of idle locked M's
// (pretending that one more is running) before the CAS. // (pretending that one more is running) before the CAS.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment