From cb6f994ae2e009b95b631fafb86d53f91bac784e Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 10 Aug 2011 11:31:03 -0700 Subject: [PATCH] --- yaml --- r: 269183 b: refs/heads/master c: dce75a8c71819ed4c7efdcd53c9b6f6356dc8cb5 h: refs/heads/master i: 269181: 2168f33b91cb753152fe7fd5767e6f608b256924 269179: 9d694bb20a4b6f8f6eebd397a6cdcc16d21c0287 269175: 3d136680f4b29d6e6e35a94dc8886dae8c90d0c2 269167: 1b1695b770eca47d4dccb93fb46406442de99793 269151: d0679a7100b30c9da2e7cb9a65b5edb0d09faaf9 269119: b1bb01111fae15b563db4fd83f8411665cf7cfc2 269055: 1a7b06a4e2b8d50267c4e5d2de10674d53b690bb v: v3 --- [refs] | 2 +- trunk/include/linux/alarmtimer.h | 2 ++ trunk/kernel/time/alarmtimer.c | 37 +++++++++++++++++++++++++++++++- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index ee2da6298ac8..140fde7e5daa 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 54da23b720d5d612f8f1669f9ed3744008fb7382 +refs/heads/master: dce75a8c71819ed4c7efdcd53c9b6f6356dc8cb5 diff --git a/trunk/include/linux/alarmtimer.h b/trunk/include/linux/alarmtimer.h index 0289eb29e794..17535963b274 100644 --- a/trunk/include/linux/alarmtimer.h +++ b/trunk/include/linux/alarmtimer.h @@ -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_cancel(struct alarm *alarm); +u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval); + #endif diff --git a/trunk/kernel/time/alarmtimer.c b/trunk/kernel/time/alarmtimer.c index 55e634ea6054..f03b04291b6f 100644 --- a/trunk/kernel/time/alarmtimer.c +++ b/trunk/kernel/time/alarmtimer.c @@ -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 * @clockid: clockid. @@ -376,7 +411,7 @@ static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm, /* Re-add periodic timers */ 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_NORESTART;