Skip to content

Commit

Permalink
Merge pull request #2515 from lightblu/master
Browse files Browse the repository at this point in the history
sys/vtimer: Fix two vtimer issues (hwtimer tick conversion).
  • Loading branch information
Joakim Gebart committed Jun 1, 2015
2 parents 4b1e158 + 2ee6ff0 commit d804969
Showing 1 changed file with 14 additions and 22 deletions.
36 changes: 14 additions & 22 deletions sys/vtimer/vtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,6 @@ static volatile int in_callback = false;
static int hwtimer_id = -1;
static uint32_t hwtimer_next_absolute;

static uint32_t seconds = 0;

static inline priority_queue_node_t *timer_get_node(vtimer_t *timer)
{
if (!timer) {
Expand Down Expand Up @@ -126,25 +124,20 @@ static int update_shortterm(void)
/* short term part of the next vtimer */
hwtimer_next_absolute = shortterm_priority_queue_root.first->priority;

uint32_t next = hwtimer_next_absolute;
uint32_t next = hwtimer_next_absolute + longterm_tick_start;

/* current short term time */
uint32_t now = HWTIMER_TICKS_TO_US(hwtimer_now());

/* make sure the longterm_tick_timer does not get truncated */
if (node_get_timer(shortterm_priority_queue_root.first)->action != vtimer_callback_tick) {
/* the next vtimer to schedule is the long term tick */
/* it has a shortterm offset of longterm_tick_start */
next += longterm_tick_start;
}
uint32_t now_ticks = hwtimer_now();
uint32_t now = HWTIMER_TICKS_TO_US(now_ticks);

if((next - HWTIMER_TICKS_TO_US(VTIMER_THRESHOLD) - now) > MICROSECONDS_PER_TICK ) {
DEBUG("truncating next (next - HWTIMER_TICKS_TO_US(VTIMER_THRESHOLD) - now): %lu\n", (next - HWTIMER_TICKS_TO_US(VTIMER_THRESHOLD) - now));
next = now + HWTIMER_TICKS_TO_US(VTIMER_BACKOFF);
}

DEBUG("update_shortterm: Set hwtimer to %" PRIu32 " (now=%lu)\n", next, HWTIMER_TICKS_TO_US(hwtimer_now()));
hwtimer_id = hwtimer_set_absolute(HWTIMER_TICKS(next), vtimer_callback, NULL);
DEBUG("update_shortterm: Set hwtimer to %" PRIu32 " (now=%lu)\n", next, now);
uint32_t next_ticks = now_ticks + HWTIMER_TICKS(next - now);
hwtimer_id = hwtimer_set_absolute(next_ticks, vtimer_callback, NULL);

return 0;
}
Expand All @@ -154,16 +147,16 @@ void vtimer_callback_tick(vtimer_t *timer)
(void) timer;

DEBUG("vtimer_callback_tick().\n");
seconds += SECONDS_PER_TICK;

longterm_tick_start = longterm_tick_timer.absolute.microseconds;
longterm_tick_timer.absolute.microseconds += MICROSECONDS_PER_TICK;
longterm_tick_start += MICROSECONDS_PER_TICK;
longterm_tick_timer.absolute.seconds += SECONDS_PER_TICK;
longterm_tick_timer.absolute.microseconds = MICROSECONDS_PER_TICK; // Should never change, just for clarity.
set_shortterm(&longterm_tick_timer);

while (longterm_priority_queue_root.first) {
vtimer_t *timer = node_get_timer(longterm_priority_queue_root.first);

if (timer->absolute.seconds == seconds) {
if (timer->absolute.seconds == longterm_tick_timer.absolute.seconds) {
priority_queue_remove_head(&longterm_priority_queue_root);
set_shortterm(timer);
}
Expand Down Expand Up @@ -271,7 +264,7 @@ static int vtimer_set(vtimer_t *timer)
}

unsigned state = disableIRQ();
if (timer->absolute.seconds != seconds) {
if (timer->absolute.seconds != longterm_tick_timer.absolute.seconds) {
/* we're long-term */
DEBUG("vtimer_set(): setting long_term\n");
result = set_longterm(timer);
Expand All @@ -295,10 +288,10 @@ static int vtimer_set(vtimer_t *timer)

void vtimer_now(timex_t *out)
{
uint32_t us = HWTIMER_TICKS_TO_US(hwtimer_now() - longterm_tick_start);
uint32_t us_per_s = 1000ul * 1000ul;
uint32_t us = HWTIMER_TICKS_TO_US(hwtimer_now()) - longterm_tick_start;
static const uint32_t us_per_s = 1000ul * 1000ul;

out->seconds = seconds + us / us_per_s;
out->seconds = longterm_tick_timer.absolute.seconds + us / us_per_s;
out->microseconds = us % us_per_s;
}

Expand Down Expand Up @@ -326,7 +319,6 @@ void vtimer_init(void)
{
DEBUG("vtimer_init().\n");
unsigned state = disableIRQ();
seconds = 0;

longterm_tick_start = 0;

Expand Down

0 comments on commit d804969

Please sign in to comment.