aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time
diff options
context:
space:
mode:
authorJohn Stultz <john.stultz@linaro.org>2011-08-10 14:31:03 -0400
committerJohn Stultz <john.stultz@linaro.org>2011-08-10 17:55:23 -0400
commitdce75a8c71819ed4c7efdcd53c9b6f6356dc8cb5 (patch)
tree76d25888bb83814fc1f9d5f8838483730ca59882 /kernel/time
parent54da23b720d5d612f8f1669f9ed3744008fb7382 (diff)
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>
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/alarmtimer.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 55e634ea605..f03b04291b6 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -347,6 +347,41 @@ void alarm_cancel(struct alarm *alarm)
347} 347}
348 348
349 349
350
351u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval)
352{
353 u64 overrun = 1;
354 ktime_t delta;
355
356 delta = ktime_sub(now, alarm->node.expires);
357
358 if (delta.tv64 < 0)
359 return 0;
360
361 if (unlikely(delta.tv64 >= interval.tv64)) {
362 s64 incr = ktime_to_ns(interval);
363
364 overrun = ktime_divns(delta, incr);
365
366 alarm->node.expires = ktime_add_ns(alarm->node.expires,
367 incr*overrun);
368
369 if (alarm->node.expires.tv64 > now.tv64)
370 return overrun;
371 /*
372 * This (and the ktime_add() below) is the
373 * correction for exact:
374 */
375 overrun++;
376 }
377
378 alarm->node.expires = ktime_add(alarm->node.expires, interval);
379 return overrun;
380}
381
382
383
384
350/** 385/**
351 * clock2alarm - helper that converts from clockid to alarmtypes 386 * clock2alarm - helper that converts from clockid to alarmtypes
352 * @clockid: clockid. 387 * @clockid: clockid.
@@ -376,7 +411,7 @@ static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
376 411
377 /* Re-add periodic timers */ 412 /* Re-add periodic timers */
378 if (alarm->period.tv64) { 413 if (alarm->period.tv64) {
379 alarm->node.expires = ktime_add(now, alarm->period); 414 ptr->it_overrun += alarm_forward(alarm, now, alarm->period);
380 return ALARMTIMER_RESTART; 415 return ALARMTIMER_RESTART;
381 } 416 }
382 return ALARMTIMER_NORESTART; 417 return ALARMTIMER_NORESTART;