alarmtimers: Add alarm_forward functionality
In order to avoid wasting time expiring and re-adding very high freq periodic alarmtimers, introduce alarm_forward() which is similar to hrtimer_forward and moves the timer to the next future expiration time and returns the number of overruns. CC: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: John Stultz <john.stultz@linaro.org>
This commit is contained in:
parent
54da23b720
commit
dce75a8c71
2 changed files with 38 additions and 1 deletions
|
@ -42,4 +42,6 @@ void alarm_init(struct alarm *alarm, enum alarmtimer_type type,
|
||||||
void alarm_start(struct alarm *alarm, ktime_t start, ktime_t period);
|
void alarm_start(struct alarm *alarm, ktime_t start, ktime_t period);
|
||||||
void alarm_cancel(struct alarm *alarm);
|
void alarm_cancel(struct alarm *alarm);
|
||||||
|
|
||||||
|
u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -347,6 +347,41 @@ void alarm_cancel(struct alarm *alarm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval)
|
||||||
|
{
|
||||||
|
u64 overrun = 1;
|
||||||
|
ktime_t delta;
|
||||||
|
|
||||||
|
delta = ktime_sub(now, alarm->node.expires);
|
||||||
|
|
||||||
|
if (delta.tv64 < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (unlikely(delta.tv64 >= interval.tv64)) {
|
||||||
|
s64 incr = ktime_to_ns(interval);
|
||||||
|
|
||||||
|
overrun = ktime_divns(delta, incr);
|
||||||
|
|
||||||
|
alarm->node.expires = ktime_add_ns(alarm->node.expires,
|
||||||
|
incr*overrun);
|
||||||
|
|
||||||
|
if (alarm->node.expires.tv64 > now.tv64)
|
||||||
|
return overrun;
|
||||||
|
/*
|
||||||
|
* This (and the ktime_add() below) is the
|
||||||
|
* correction for exact:
|
||||||
|
*/
|
||||||
|
overrun++;
|
||||||
|
}
|
||||||
|
|
||||||
|
alarm->node.expires = ktime_add(alarm->node.expires, interval);
|
||||||
|
return overrun;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clock2alarm - helper that converts from clockid to alarmtypes
|
* clock2alarm - helper that converts from clockid to alarmtypes
|
||||||
* @clockid: clockid.
|
* @clockid: clockid.
|
||||||
|
@ -376,7 +411,7 @@ static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
|
||||||
|
|
||||||
/* Re-add periodic timers */
|
/* Re-add periodic timers */
|
||||||
if (alarm->period.tv64) {
|
if (alarm->period.tv64) {
|
||||||
alarm->node.expires = ktime_add(now, alarm->period);
|
ptr->it_overrun += alarm_forward(alarm, now, alarm->period);
|
||||||
return ALARMTIMER_RESTART;
|
return ALARMTIMER_RESTART;
|
||||||
}
|
}
|
||||||
return ALARMTIMER_NORESTART;
|
return ALARMTIMER_NORESTART;
|
||||||
|
|
Loading…
Reference in a new issue