[PATCH] hrtimers: posix-timer: cleanup common_timer_get()
Roman Zippel [Sun, 26 Mar 2006 09:38:07 +0000 (01:38 -0800)]
Cleanup common_timer_get() a little.

Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

kernel/posix-timers.c

index 255657a..7c5f447 100644 (file)
@@ -608,39 +608,41 @@ static struct k_itimer * lock_timer(timer_t timer_id, unsigned long *flags)
 static void
 common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
 {
-       ktime_t remaining;
+       ktime_t now, remaining, iv;
        struct hrtimer *timer = &timr->it.real.timer;
 
        memset(cur_setting, 0, sizeof(struct itimerspec));
-       remaining = hrtimer_get_remaining(timer);
 
-       /* Time left ? or timer pending */
-       if (remaining.tv64 > 0 || hrtimer_active(timer))
-               goto calci;
+       iv = timr->it.real.interval;
+
        /* interval timer ? */
-       if (timr->it.real.interval.tv64 == 0)
+       if (iv.tv64)
+               cur_setting->it_interval = ktime_to_timespec(iv);
+       else if (!hrtimer_active(timer) &&
+                (timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE)
                return;
+
+       now = timer->base->get_time();
+
        /*
-        * When a requeue is pending or this is a SIGEV_NONE timer
-        * move the expiry time forward by intervals, so expiry is >
-        * now.
+        * When a requeue is pending or this is a SIGEV_NONE
+        * timer move the expiry time forward by intervals, so
+        * expiry is > now.
         */
-       if (timr->it_requeue_pending & REQUEUE_PENDING ||
-           (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE) {
-               timr->it_overrun +=
-                       hrtimer_forward(timer, timer->base->get_time(),
-                                       timr->it.real.interval);
-               remaining = hrtimer_get_remaining(timer);
-       }
- calci:
-       /* interval timer ? */
-       if (timr->it.real.interval.tv64 != 0)
-               cur_setting->it_interval =
-                       ktime_to_timespec(timr->it.real.interval);
+       if (iv.tv64 && (timr->it_requeue_pending & REQUEUE_PENDING ||
+           (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE))
+               timr->it_overrun += hrtimer_forward(timer, now, iv);
+
+       remaining = ktime_sub(timer->expires, now);
        /* Return 0 only, when the timer is expired and not pending */
-       if (remaining.tv64 <= 0)
-               cur_setting->it_value.tv_nsec = 1;
-       else
+       if (remaining.tv64 <= 0) {
+               /*
+                * A single shot SIGEV_NONE timer must return 0, when
+                * it is expired !
+                */
+               if ((timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE)
+                       cur_setting->it_value.tv_nsec = 1;
+       } else
                cur_setting->it_value = ktime_to_timespec(remaining);
 }