Several issues:
- `last_count` should not be updated with current time or this will
cause a time drift and induce jitter due to IRQ servicing latency.
- `sys_clock_set_timeout()` should not base its `mtime` on the current
time either. Tracking the `last_tick` and `last_elapsed` values avoids
the need for all the tick rounding computation.
- The MIN_DELAY thing is pointless. If the delay gets close or even behind
current time then the IRQ will be triggered right away. This is unlikely
to happen very often anyway so the constant overhead is uncalled for.
- Runtime 64-bits divisions on 32-bits hardware are very expensive.
Fix the above, and improve the following:
- Prime the accounting by simply invoking the IRQ handler from the init
code. That will make the "ticks since boot" counter right.
- Remove excessive casts, especially a few wrong ones.
- Simplify the code overall.
Here's the output from the timer_jitter_drift test.
Before this patch:
|timer clock rate 60000000, kernel tick rate 10000
|period duration statistics for 10000 samples (0 rollovers):
| expected: 1000 us, 60000.000000 cycles
| min: 907.600000 us, 54456 cycles
| max: 1099.750000 us, 65985 cycles
| mean: 1008.594633 us, 60515.678000 cycles
| variance: 2.184205 us, 7863.136316 cycles
| stddev: 1.477906 us, 88.674332 cycles
|timer start cycle 995589, end cycle 606152369,
|total time 10085946.333333 us, expected time 10000000.000000 us,
|expected time drift 0.000000 us, difference 85946.333333 us
After this patch:
|timer clock rate 60000000, kernel tick rate 10000
|period duration statistics for 10000 samples (0 rollovers):
| expected: 1000 us, 60000.000000 cycles
| min: 992.116667 us, 59527 cycles
| max: 1030.366667 us, 61822 cycles
| mean: 1000.001902 us, 60000.114100 cycles
| variance: 0.105334 us, 379.201081 cycles
| stddev: 0.324551 us, 19.473087 cycles
|timer start cycle 987431, end cycle 600988572,
|total time 10000019.016667 us, expected time 10000000.000000 us,
|expected time drift 0.000000 us, difference 19.016667 us
The mean, variance and standard deviation number differences speak for
themselves, even in the absence of competing ISRs and/or IRQ-disabled
periods which would have made the comparison even worse.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>