277: TimerQueue.dequeue: don't set SYST reload to 0 r=korken89 a=mpasternacki
ARM Architecture Reference Manual says: "Setting SYST_RVR to zero has the effect of disabling the SysTick counter independently of the counter enable bit."
If Monotonic's ratio is less than one, the timeout calculations
can compute zero if next task is scheduled after current instant, but
before next timer tick. This results in disabling SYST and freezing the
timer queue.
The division by ratio's denominator rounds downward and the dequeue
condition is `if instant < now`. If ratio is small enough, this results
in unnecessary interrupts:
Let's say `instant - now` is 99 and ratio is 1/25. Then, `dur` will
equal 3 and the next tick will happen at `now + 75`. In the next
interrupt, `instant > now` and additional tick needs to be scheduled
(which doesn't happen, because now `instant - now` is less than 25, so
reload will be set to 0 and timer queue will stop). Adding one to
computed duration will prevent both freezing and additional interrupts.
When ratio is 1 or close, timer queue code overhead will prevent this
from happening. I am working with a chip where CPU is clocked at 600MHz
and SysTick is 100kHz and the freeze happens quite often.
Co-authored-by: Maciej Pasternacki <maciej@3ofcoins.net>
ARM Architecture Reference Manual says: "Setting SYST_RVR to zero has the effect of disabling the SysTick counter independently of the counter enable bit."
If Monotonic's ratio is less than one, the timeout calculations
can compute zero if next task is scheduled after current instant, but
before next timer tick. This results in disabling SYST and freezing the
timer queue.
originally the type was made `!Send` because it loses its meaning when
send from one core to another but that was an incorrect use of the `Send`
bound (the send operation makes the value incorrect but that doesn't cause
memory unsafety on its own). So later the type was (explicitly) made `Send`
again resulting in a convoluted implementation -- this commit simplifies things.