diff options
| author | John Stultz <john.stultz@linaro.org> | 2011-08-10 14:31:03 -0400 |
|---|---|---|
| committer | John Stultz <john.stultz@linaro.org> | 2011-08-10 17:55:23 -0400 |
| commit | dce75a8c71819ed4c7efdcd53c9b6f6356dc8cb5 (patch) | |
| tree | 76d25888bb83814fc1f9d5f8838483730ca59882 /kernel | |
| parent | 54da23b720d5d612f8f1669f9ed3744008fb7382 (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')
| -rw-r--r-- | kernel/time/alarmtimer.c | 37 |
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 | |||
| 351 | u64 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; |
