mirror of
https://github.com/apache/nuttx.git
synced 2026-05-30 05:16:47 +08:00
POSIX timer: Optimize overrun check by replacing loop with division.
Converted the timer overrun check from a loop-based approach to a division-based method. This change ensures a deterministic worst-case execution time (WCET), even if it might not outperform the loop in average scenarios. Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
This commit is contained in:
committed by
Xiang Xiao
parent
578ecef975
commit
5a01f0f7f6
+17
-11
@@ -98,6 +98,7 @@ static inline void timer_restart(FAR struct posix_timer_s *timer,
|
|||||||
{
|
{
|
||||||
clock_t ticks;
|
clock_t ticks;
|
||||||
sclock_t delay;
|
sclock_t delay;
|
||||||
|
sclock_t frame;
|
||||||
|
|
||||||
/* If this is a repetitive timer, then restart the watchdog */
|
/* If this is a repetitive timer, then restart the watchdog */
|
||||||
|
|
||||||
@@ -106,19 +107,24 @@ static inline void timer_restart(FAR struct posix_timer_s *timer,
|
|||||||
/* Check whether next expected time is reached */
|
/* Check whether next expected time is reached */
|
||||||
|
|
||||||
ticks = clock_systime_ticks();
|
ticks = clock_systime_ticks();
|
||||||
timer->pt_overrun = 0;
|
delay = ticks - timer->pt_expected;
|
||||||
|
|
||||||
for (; ; )
|
/* Calculate the number of timer overruns and the next expected tick.
|
||||||
{
|
* The next expired tick frame can be computed as align up:
|
||||||
timer->pt_expected += timer->pt_delay;
|
* frame <- (elapsed_ticks + pt_delay) / pt_delay
|
||||||
delay = timer->pt_expected - ticks;
|
* For instance:
|
||||||
if (delay > 0)
|
* | pt_delay | pt_delay | pt_delay | ... |
|
||||||
{
|
* ^ pt_expected ^ ticks ^ next pt_expected
|
||||||
break;
|
* In this case, frame equals 3.
|
||||||
}
|
* Then, pt_overrun <- frame - 1 and
|
||||||
|
* the next pt_expected <- pt_expected + frame * pt_delay.
|
||||||
|
* Assumption of correctness:
|
||||||
|
* (delay + timer->pt_delay) should not overflow.
|
||||||
|
*/
|
||||||
|
|
||||||
timer->pt_overrun++;
|
frame = (delay + timer->pt_delay) / timer->pt_delay;
|
||||||
}
|
timer->pt_overrun = frame - 1;
|
||||||
|
timer->pt_expected += frame * timer->pt_delay;
|
||||||
|
|
||||||
wd_start_abstick(&timer->pt_wdog, timer->pt_expected,
|
wd_start_abstick(&timer->pt_wdog, timer->pt_expected,
|
||||||
timer_timeout, itimer);
|
timer_timeout, itimer);
|
||||||
|
|||||||
Reference in New Issue
Block a user