[PATCH -rt] speed up nanosleep on early expire

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

 



Here's a revisit of the problem of nanosleep waking up the softirq to wake
itself up when the timer has already expired.  As mentioned in my last
patch, this causes large latencies to nanosleep.  But the last patch was
sloppy and introduced too much ugly code.

I should have noticed this the first time, but here's a much cleaner
patch.  As the hrtimer_interrupt checks the data field to determine to
wake the process up directly or to wake up the softirq, I noticed that the
nanosleep doesn't even need the softirq.  So instead of waking up the
softirq in enqueue_hrtimer, I do the same work as the hrtimer_interrupt
does, and that is to wake up the process directly if there is no function
associated with the timer.

I also saved a few microseconds by checking in schedule_hrtimer if current
is already running don't call schedule.

This patch is much cleaner than the last patch, and gives pretty much the
same result.

-- Steve

Signed-off-by: Steven Rostedt <[email protected]>

Index: linux-2.6.15-rt16/kernel/hrtimer.c
===================================================================
--- linux-2.6.15-rt16.orig/kernel/hrtimer.c	2006-02-10 09:53:53.000000000 -0500
+++ linux-2.6.15-rt16/kernel/hrtimer.c	2006-02-14 04:30:43.000000000 -0500
@@ -578,9 +578,18 @@
 		 * and schedule the softirq.
 		 */
 		if (hrtimer_hres_active && hrtimer_reprogram(timer, base)) {
-			list_add_tail(&timer->list, &base->expired);
-			timer->state = HRTIMER_PENDING_CALLBACK;
-			raise_softirq(HRTIMER_SOFTIRQ);
+			/*
+			 * Only wake up the hrtimer softirq if it is needed,
+			 * otherwise wake up the process waiting for this timer.
+			 */
+			if (!timer->function) {
+				wake_up_process(timer->data);
+				timer->state = HRTIMER_EXPIRED;
+			} else {
+				list_add_tail(&timer->list, &base->expired);
+				timer->state = HRTIMER_PENDING_CALLBACK;
+				raise_softirq(HRTIMER_SOFTIRQ);
+			}
 			return;
 		}
 #endif
@@ -1029,7 +1038,13 @@

 	hrtimer_start(timer, timer->expires, mode);

-	schedule();
+	/*
+	 * the timer could have arleady expired, in which
+	 * case current would be running. Don't bother calling
+	 * schedule.
+	 */
+	if (likely(current->state))
+		schedule();
 	hrtimer_cancel(timer);

 	/* Return the remaining time: */
-
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