Skip to content

Commit

Permalink
Merge pull request #13237 from MichelRottleuthner/pr_bp13212
Browse files Browse the repository at this point in the history
sys/xtimer: compare two offsets rather than absolute times [backport 2020.01]
  • Loading branch information
aabadie authored Jan 30, 2020
2 parents e347f0a + a310ff9 commit 97f8832
Showing 1 changed file with 17 additions and 13 deletions.
30 changes: 17 additions & 13 deletions sys/xtimer/xtimer_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ static xtimer_t *timer_list_head = NULL;
static xtimer_t *long_list_head = NULL;
static bool _lltimer_ongoing = false;

static void _add_timer_to_list(xtimer_t **list_head, xtimer_t *timer);
static void _add_timer_to_list(xtimer_t **list_head, xtimer_t *timer, uint32_t now);
static void _shoot(xtimer_t *timer);
static inline void _update_short_timers(uint64_t *now);
static inline void _update_long_timers(uint64_t *now);
Expand Down Expand Up @@ -93,15 +93,15 @@ void _xtimer_set64(xtimer_t *timer, uint32_t offset, uint32_t long_offset)
timer->long_start_time = (uint32_t)(now >> 32);

if (!long_offset) {
_add_timer_to_list(&timer_list_head, timer);
_add_timer_to_list(&timer_list_head, timer, (uint32_t)now);

if (timer_list_head == timer) {
DEBUG("_xtimer_set64(): timer is new list head. updating lltimer.\n");
_schedule_earliest_lltimer((uint32_t)now);
}
}
else {
_add_timer_to_list(&long_list_head, timer);
_add_timer_to_list(&long_list_head, timer, (uint32_t)now);
DEBUG("_xtimer_set64(): added longterm timer.\n");
}
irq_restore(state);
Expand Down Expand Up @@ -148,27 +148,31 @@ static inline void _schedule_earliest_lltimer(uint32_t now)
/**
* @brief compare two timers. return true if timerA expires earlier than or equal to timerB and false otherwise.
*/
static bool _timer_comparison(xtimer_t* timerA, xtimer_t* timerB)
static bool _timer_comparison(xtimer_t* timerA, xtimer_t* timerB, uint32_t now)
{
if (timerA->long_offset < timerB->long_offset) {
return true;
}
if (timerA->long_offset == timerB->long_offset
/* this condition is needed for when timerA was already expired before timerB starts */
&& (timerA->start_time + timerA->offset < timerB->start_time
/* it is necessary to compare two offsets, instead of two absolute times */
|| timerA->start_time + timerA->offset - timerB->start_time <= timerB->offset)) {
return true;
if (timerA->long_offset == timerB->long_offset) {
uint32_t elapsedA = now - timerA->start_time;
uint32_t elapsedB = now - timerB->start_time;
/* it is necessary to compare two offsets, instead of two absolute times
* two conditions: (1) timerA was already expired
* (2) timerA will expire earlier than or equal to timerB
*/
if (timerA->offset < elapsedA || timerA->offset - elapsedA <= timerB->offset - elapsedB) {
return true;
}
}
return false;
}

/**
* @brief add a timer to an ordered list of timers
*/
static void _add_timer_to_list(xtimer_t **list_head, xtimer_t *timer)
static void _add_timer_to_list(xtimer_t **list_head, xtimer_t *timer, uint32_t now)
{
while (*list_head && _timer_comparison((*list_head), timer)) {
while (*list_head && _timer_comparison((*list_head), timer, now)) {
list_head = &((*list_head)->next);
}

Expand Down Expand Up @@ -227,7 +231,7 @@ static inline void _update_long_timers(uint64_t *now)
assert(timer == long_list_head);

_remove_timer_from_list(&long_list_head, timer);
_add_timer_to_list(&timer_list_head, timer);
_add_timer_to_list(&timer_list_head, timer, (uint32_t)*now);
timer = long_list_head;
}
else {
Expand Down

0 comments on commit 97f8832

Please sign in to comment.