diff options
-rw-r--r-- | include/linux/alarmtimer.h | 1 | ||||
-rw-r--r-- | kernel/time/alarmtimer.c | 24 |
2 files changed, 18 insertions, 7 deletions
diff --git a/include/linux/alarmtimer.h b/include/linux/alarmtimer.h index 975009e1cbe6..9a9838ad27d4 100644 --- a/include/linux/alarmtimer.h +++ b/include/linux/alarmtimer.h @@ -48,6 +48,7 @@ int alarm_try_to_cancel(struct alarm *alarm); int alarm_cancel(struct alarm *alarm); u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval); +ktime_t alarm_expires_remaining(const struct alarm *alarm); /* * A alarmtimer is active, when it is enqueued into timerqueue or the diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index eb198a3ae7c3..a13a5dc6bc29 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -226,6 +226,12 @@ static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer) } +ktime_t alarm_expires_remaining(const struct alarm *alarm) +{ + struct alarm_base *base = &alarm_bases[alarm->type]; + return ktime_sub(alarm->node.expires, base->gettime()); +} + #ifdef CONFIG_RTC_CLASS /** * alarmtimer_suspend - Suspend time callback @@ -519,18 +525,22 @@ static int alarm_timer_create(struct k_itimer *new_timer) * @new_timer: k_itimer pointer * @cur_setting: itimerspec data to fill * - * Copies the itimerspec data out from the k_itimer + * Copies out the current itimerspec data */ static void alarm_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) { - memset(cur_setting, 0, sizeof(struct itimerspec)); + ktime_t relative_expiry_time = + alarm_expires_remaining(&(timr->it.alarm.alarmtimer)); + + if (ktime_to_ns(relative_expiry_time) > 0) { + cur_setting->it_value = ktime_to_timespec(relative_expiry_time); + } else { + cur_setting->it_value.tv_sec = 0; + cur_setting->it_value.tv_nsec = 0; + } - cur_setting->it_interval = - ktime_to_timespec(timr->it.alarm.interval); - cur_setting->it_value = - ktime_to_timespec(timr->it.alarm.alarmtimer.node.expires); - return; + cur_setting->it_interval = ktime_to_timespec(timr->it.alarm.interval); } /** |