[PATCH 6/9] handle lost timer ticks in ptimer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This changes how ptimer deals with lost timer ticks (as far as they can be
detected).  If ticks have been lost, the runqueue is run repeatedly until it
has catched up with the current time. As lost ticks is a rather uncommon event,
I think it's a lot better to deal with it at a single place.

This mean the ptimer users don't have to deal with this anymore and makes them
simpler, e.g. itimer doesn't doesn't has to loop anymore to update the expire
value and posix-timer avoids calling schedule_next_timer().

Signed-off-by: Roman Zippel <[email protected]>

---

 kernel/itimer.c       |    3 +--
 kernel/posix-timers.c |   12 +++++++++---
 kernel/ptimer.c       |   13 ++++++++++++-
 3 files changed, 22 insertions(+), 6 deletions(-)

Index: linux-2.6-mm/kernel/itimer.c
===================================================================
--- linux-2.6-mm.orig/kernel/itimer.c	2005-11-28 22:31:00.000000000 +0100
+++ linux-2.6-mm/kernel/itimer.c	2005-11-28 22:31:10.000000000 +0100
@@ -132,8 +132,7 @@ int it_real_fn(struct ptimer *timer)
 	 */
 	if (!inc)
 		return 0;
-	while (time_before_eq(sig->real_timer.expires, jiffies))
-		sig->real_timer.expires += inc;
+	sig->real_timer.expires += inc;
 	return 1;
 }
 
Index: linux-2.6-mm/kernel/posix-timers.c
===================================================================
--- linux-2.6-mm.orig/kernel/posix-timers.c	2005-11-28 22:31:08.000000000 +0100
+++ linux-2.6-mm/kernel/posix-timers.c	2005-11-28 22:31:10.000000000 +0100
@@ -500,9 +500,15 @@ static int posix_timer_fn(struct ptimer 
 	}
 
 	if (!timr->it_requeue_pending) {
-		if (!posix_timer_event(timr, 1))
-			timr->it_requeue_pending = 1;
-		do_restart = schedule_next_timer(timr);
+		timr->it_requeue_pending = 1;
+		if (unlikely(posix_timer_event(timr, 1))) {
+			timr->it_requeue_pending = 0;
+			timr->it_overrun++;
+		}
+		if (timr->it.real.incr) {
+			timr->it.real.timer.expires += timr->it.real.incr;
+			do_restart = 1;
+		}
 	} else {
 		timr->it_requeue_pending = 2;
 		timr->it_overrun++;
Index: linux-2.6-mm/kernel/ptimer.c
===================================================================
--- linux-2.6-mm.orig/kernel/ptimer.c	2005-11-28 22:31:00.000000000 +0100
+++ linux-2.6-mm/kernel/ptimer.c	2005-11-28 22:31:10.000000000 +0100
@@ -252,9 +252,20 @@ static inline void ptimer_run_queue(stru
 void ptimer_run_queues(void)
 {
 	struct ptimer_base *base;
+	unsigned long expired, now = jiffies;
 
 	base = __get_cpu_var(ptimer_bases);
-	base->last_expired = jiffies;
+
+	expired = base[CLOCK_MONOTONIC].last_expired + 1;
+	if (unlikely(expired != now)) {
+		if (time_after(expired, now))
+			return;
+		do {
+			base[CLOCK_MONOTONIC].last_expired = expired;
+			ptimer_run_queue(&base[CLOCK_MONOTONIC]);
+		} while (++expired != now);
+	}
+	base[CLOCK_MONOTONIC].last_expired = jiffies;
 	ptimer_run_queue(&base[CLOCK_MONOTONIC]);
 }
 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux