<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>Cross posting since at this level systems are still very similar.</div><div><br></div><div dir="ltr">I've sometimes wondered about how the idle process </div><div dir="ltr">relinquishing the CPU interacted with delay scheduling, </div><div dir="ltr">since they operate at the extreme opposite ends of process priorities.</div><div dir="ltr"><br></div><div>Historically there was...</div><div><div>ProcessorScheduler class >> idleProcess</div><div>[    "A default background process which is invisible."</div><div>     [true] whileTrue:</div><div>         [self relinquishProcessorForMicroseconds: 1000]     </div></div><div><br></div><div>which had the following performance this for later comparison...<br>    (1 to: 10) collect: [:i | [ (Delay forMilliseconds: 1) wait ] timeToRun asMilliSeconds].</div><div>    ==> "#(2 5 4 2 4 4 2 4 4 3)"<br></div><div><br></div><div>To improve battery life yield time Pharo changed this to 50000 in... </div><div>* <a href="https://pharo.fogbugz.com/f/cases/20425/Yield-longer-in-ProcessorScheduler-idleProcess">https://pharo.fogbugz.com/f/cases/20425/Yield-longer-in-ProcessorScheduler-idleProcess</a></div><div>* <a href="https://github.com/pharo-project/pharo/commit/0b0d12dc">https://github.com/pharo-project/pharo/commit/0b0d12dc</a><br></div><div>but had a negative impact on delays... <br></div><div><div>    (1 to: 10) collect: [:i | [ (Delay forMilliseconds: 1) wait ] timeToRun asMilliSeconds].</div>   ==> "#(36 51 50 51 50 51 51 30 50 50)"<br></div><div>as reported... <a href="https://pharo.fogbugz.com/f/cases/22400/Delays-are-not-working-properly">https://pharo.fogbugz.com/f/cases/22400/Delays-are-not-working-properly</a></div><div><br></div><div>The problem seems to be that #relinquishProcessorForMicroseconds: suspends the main VM thread for a fixed amount during which expired delays cannot be dealt with.  I'm not sure of the exact mechanism in the VM but this looks related...</div><div>Win: <a href="https://github.com/OpenSmalltalk/opensmalltalk-vm/blob/e2fa2d1/platforms/win32/vm/sqWin32Window.c#L1593">https://github.com/OpenSmalltalk/opensmalltalk-vm/blob/e2fa2d1/platforms/win32/vm/sqWin32Window.c#L1593</a><br></div><div>Mac: <a href="https://github.com/OpenSmalltalk/opensmalltalk-vm/blob/a8a1dc1/platforms/unix/vm/sqUnixHeartbeat.c#L263">https://github.com/OpenSmalltalk/opensmalltalk-vm/blob/a8a1dc1/platforms/unix/vm/sqUnixHeartbeat.c#L263</a> <br></div><div>I'm not sure about Linux</div><div><br></div><div>One idea was to have a setting, but another path is to mix the idle-relinquish </div><div>into the delay-scheduling to dynamically relinquish up to exactly when the activeDelay expires.</div><div><br></div><div><div><div>After loading...</div><div>   <a href="https://github.com/pharo-project/pharo/pull/1887">https://github.com/pharo-project/pharo/pull/1887</a><br></div>you can do...</div><div><div>    DelayIdleTicker installExperiment.</div><div>    (1 to: 10) collect: [:i | [ (Delay forMilliseconds: 1) wait ] timeToRun asMilliSeconds].</div><div>==>"#(1 1 2 2 2 2 2 2 2 2)" which btw is half the latency of the original</div><div>    DelayIdleTicker debug: true.  "CPU usage goes way up"</div><div>    DelayIdleTicker uninstall.</div></div></div><div><br></div><div>I'm now seeking:</div><div>* comment on how this might interact with parts of the VM I'm not familiar with.</div><div>* help to discover and stress test corner cases.  <br></div><div>* help to determine if there actually is a benefit and characterize what that is,</div><div>especially anyone familiar with headless images with reduced UI and I/O events.</div><div>I was surprised to see the existing system already often showed 0% CPU usage (in Windows).</div><div><br></div><div><div>cheers -ben</div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div>