The timeout of the next timer is a good proxy for when we are planning
to wake up for as long as we are always intending to wake-up for the
next timer but that is going to stop being the case soon.
Differential Revision: https://phabricator.services.mozilla.com/D173102
Really we want to wake-up the Timer Thread now if the newly-added timer
wants to fire before the Timer Thread was scheduled to wake up. The
previous logic happened to work correctly under previous insertion
behavior isn't correct now.
Differential Revision: https://phabricator.services.mozilla.com/D168496
Due to the possible presence of canceled timers at the "front" of the
list, mTimers[0] won't necessarily hold the next timer to be fired
unless we've cleaned up those front timers recently.
Differential Revision: https://phabricator.services.mozilla.com/D166575
The previous version used IndexOfFirstElementGt which is implemented
with a binary search. That doesn't work correctly because the mTimers
array that is being searched is maintained in sorted order
*only if the "cancelled" timers are skipped*. This revision replaces the
binary search with a linear search which can handle this without
problem. Given that the number of timers present at any one time is
fairly modest, a linear search is probably a more appropriate choice
anyway.
Also added a new function, VerifyTimerListConsistency, which is called
once per wake-up in the main loop and enabled only in DEBUG builds, that
checks mTimers for ordering and consistency.
Differential Revision: https://phabricator.services.mozilla.com/D164294
This makes the code more complex, but it is needed to keep this most-used
function efficient related to its old implementation using `std::push_heap`.
Differential Revision: https://phabricator.services.mozilla.com/D164292
Inserting elements in the sorted array is more costly than pushing to a binary
heap, but this is balanced by the removal of indirections and de/allocations,
and the upcoming re-use of empty entries.
In the end, this change is necessary to allow future improvements like timer-
coalescing, where we'll need to see multiple timers in order.
Bonus: FindNextFireTimeForCurrentThread changes a lot, because it used to have
to `pop_heap` elements and then `push_heap` them back! (Sometimes resulting in
subtle changes for timers with the same timeout.) So this one benefits the
most.
Differential Revision: https://phabricator.services.mozilla.com/D164291
So entries now store the given timeout value (instead of clamping it to after "now").
And we store this timeout first, as it's accessed more frequently.
Differential Revision: https://phabricator.services.mozilla.com/D164288
This ensures that 0-delay timers are executed very quickly; without this, they
would rely on the timer thread waking up "naturally" as scheduled, but on some
platforms there could be significant delays (many milliseconds) before the
thread would actually wake up, compared to notifications that are handled
almost immediately.
Even though by specs, timers may be subject to being late, some users of
0-delay timers, in particular through JS' `setTimeout(code, 0)`, rely on the
code being executed as soon as possible (i.e., queued pretty much immediately
on the event loop).
Until now, this was almost guaranteed by the very frequent calls to
RemoveTimer, which always notified the timer thread and made it wake up very
quickly.
However the following patch is going to remove notifications from RemoveTimer,
so before that one lands we now need to ensure that 0-delay timer will still
be invoked at least as quickly as before.
Depends on D146030
Differential Revision: https://phabricator.services.mozilla.com/D149706
Modify the code so that instead of getting microseconds by first
getting milliseconds, then multiplying by 1000, it retrieves the
microseconds value directly.
Differential Revision: https://phabricator.services.mozilla.com/D143472