MessagePumpDefault can spin for up to 1 ms on Windows

There are two power efficiency issues that this change is trying
to address:

1) On Windows if we call event_.TimedWait(delay) with a sub-ms
delay then the wait function will return promptly.
This means we end up busy-waiting down to zero.
Rounding these times up to 1 ms lets Chrome go idle.
ETW profiles show that the spinning makes the message
loop inefficient. In some cases up to 50% of all inclusive
MessagePumpDefault::Run cycles are spent inside the timed
wait.

2) On Windows versions 7 and above wait functions (Sleep,
WaitForSingleObject, WaitForMultipleObjects, etc) time out
up to 1 ms earlier. That results in iterating through the
loop with no new work available (the event isn't
set) and too early for delayed tasks to run.
This change adds an inner loop around just event_.TimedWait(delay)
that makes it go straight to wait for the remaining part of
the delay should it wake up too early.

This change will trigger a regression in "percentage smooth"
metric of smoothness.top_25_smooth benchmark. But giving an
increasing focus on power consumption (when running on
batteries) it might be worth fixing this now and deal with
the smoothness benchmark regression later (see below).

"Percentage smooth" uses deltas between Renderer / Browser swap
timestamps as an estimation for frame times and counts the
percentage of frames under 17 ms. This makes the metric overly
sensitive to even slight delays in scheduling of swaps which
are mostly avoided in the current implementation due to busy-
spinning the loop in the last millisecond of the wait. Swap times
can actually move forward & backward inside a frame and still meet
V-sync which the existing implementation can't tell without
the actual frame statistics.

I've filed crbug.com/614154 and crbug.com/614147 to track a more
accurate implementation of "Percentage smooth" on Windows.

BUG=487724

Review-Url: https://codereview.chromium.org/2086123002
Cr-Commit-Position: refs/heads/master@{#402027}
1 file changed