diff --git a/hermit/include/hermit/time.h b/hermit/include/hermit/time.h index c599cef7f..c38c5a518 100644 --- a/hermit/include/hermit/time.h +++ b/hermit/include/hermit/time.h @@ -83,6 +83,8 @@ static inline void sleep(unsigned int sec) { timer_wait(sec*TIMER_FREQ); } static inline int timer_deadline(uint32_t t) { return apic_timer_deadline(t); } +static inline void timer_disable() { apic_disable_timer(); } + #ifdef __cplusplus } #endif diff --git a/hermit/kernel/tasks.c b/hermit/kernel/tasks.c index d5d091358..8ace3b7b8 100644 --- a/hermit/kernel/tasks.c +++ b/hermit/kernel/tasks.c @@ -587,8 +587,24 @@ int wakeup_task(tid_t id) task->prev->next = task->next; if (task->next) task->next->prev = task->prev; - if (readyqueues[core_id].timers.first == task) + if (readyqueues[core_id].timers.first == task) { readyqueues[core_id].timers.first = task->next; + +#ifdef DYNAMIC_TICKS + const task_t* first = readyqueues[core_id].timers.first; + if(first) { + if(first->timeout > get_clock_tick()) { + timer_deadline(first->timeout - get_clock_tick()); + } else { + // workaround: start timer so new head will be serviced + timer_deadline(1); + } + } else { + // prevent spurious interrupts + timer_disable(); + } +#endif + } if (readyqueues[core_id].timers.last == task) readyqueues[core_id].timers.last = task->prev; }