diff --git a/include/nuttx/hrtimer.h b/include/nuttx/hrtimer.h index bd8b05c2c52..f416cbb18d4 100644 --- a/include/nuttx/hrtimer.h +++ b/include/nuttx/hrtimer.h @@ -36,6 +36,18 @@ #include #include +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The maximum delay tick should be INT64_MAX. However, if there are expired + * hrtimer in the queue, HRTIMER_TIME_BEFORE/AFTER might be incorrect, so we + * limited the delay to INT64_MAX >> 1, assuming all expired hrtimer can be + * processed within HRTIMER_MAX_DELAY. + */ + +#define HRTIMER_MAX_DELAY (INT64_MAX >> 1) + /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/sched/hrtimer/hrtimer_start.c b/sched/hrtimer/hrtimer_start.c index d270dd21eee..3f6b9e09118 100644 --- a/sched/hrtimer/hrtimer_start.c +++ b/sched/hrtimer/hrtimer_start.c @@ -64,9 +64,22 @@ int hrtimer_start(FAR hrtimer_t *hrtimer, hrtimer_entry_t func, uint64_t expired, enum hrtimer_mode_e mode) { + uint64_t next_expired; irqstate_t flags; int ret = OK; + /* Compute absolute expiration time */ + + if (mode == HRTIMER_MODE_ABS) + { + next_expired = expired; + } + else + { + expired = expired <= HRTIMER_MAX_DELAY ? expired : HRTIMER_MAX_DELAY; + next_expired = clock_systime_nsec() + expired; + } + DEBUGASSERT(hrtimer != NULL); /* Protect container manipulation with spinlock and disable interrupts */ @@ -82,22 +95,8 @@ int hrtimer_start(FAR hrtimer_t *hrtimer, hrtimer_entry_t func, hrtimer_remove(hrtimer); } - hrtimer->func = func; - - /* Compute absolute expiration time */ - - if (mode == HRTIMER_MODE_ABS) - { - hrtimer->expired = expired; - } - else - { - hrtimer->expired = clock_systime_nsec() + expired; - } - - /* Ensure expiration time does not overflow */ - - DEBUGASSERT(hrtimer->expired >= expired); + hrtimer->func = func; + hrtimer->expired = next_expired; /* Insert the timer into the container */