Hi,
In an effort to reduce power consumption on my laptop, I'm trying out different patches to reduce the amount of wakeups on my machine and tracing the process using the powertop utility. One of the biggest offenders for my laptop is the do_setitimer function in Xorg. Arjan van de Ven has developed a patch which optimises the smart scheduler and works around this problem. [1] I have been using this patch now for a couple of days without noticing any problems and it has reduced the amount of ticks per second immensly.

Please review and consider for inclusion in Ubuntu Hardy.

With kind regards,
Erik Andrén

[1] http://www.bughost.org/pipermail/power/2007-October/001107.html
>From 48e4d08e99de41047c6b6fde5ba9d12787881c23 Mon Sep 17 00:00:00 2001
From: root <[EMAIL PROTECTED]>
Date: Sun, 28 Oct 2007 09:37:52 +0100
Subject: [PATCH] The smart scheduler itimer currently always fires after each request
 (which in turn causes the CPU to wake out of idle, burning precious power).
 Rather than doing this, just stop the timer before going into the select()
 portion of the WaitFor loop. It's a cheap system call, and it will only get
 called if there's no more commands batched up from the active fd.

This change also allows some of the functions to be simplified; setitimer()
will only fail if it's passed invalid data, and we don't do that... so make
it void and remove all the conditional code that deals with failure.

The change also allows us to remove a few variables that were used for
housekeeping between the signal handler and the main loop.
---
 include/dixstruct.h |    6 ++----
 os/WaitFor.c        |   11 +++--------
 os/utils.c          |   28 +++-------------------------
 3 files changed, 8 insertions(+), 37 deletions(-)

diff --git a/include/dixstruct.h b/include/dixstruct.h
index dd6347f..bed31dc 100644
--- a/include/dixstruct.h
+++ b/include/dixstruct.h
@@ -150,11 +150,9 @@ extern long SmartScheduleTime;
 extern long SmartScheduleInterval;
 extern long SmartScheduleSlice;
 extern long SmartScheduleMaxSlice;
-extern unsigned long SmartScheduleIdleCount;
 extern Bool SmartScheduleDisable;
-extern Bool SmartScheduleIdle;
-extern Bool SmartScheduleTimerStopped;
-extern Bool SmartScheduleStartTimer(void);
+extern void SmartScheduleStartTimer(void);
+extern void SmartScheduleStopTimer(void);
 #define SMART_MAX_PRIORITY  (20)
 #define SMART_MIN_PRIORITY  (-20)
 
diff --git a/os/WaitFor.c b/os/WaitFor.c
index ec1592c..7683477 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -217,7 +217,8 @@ WaitForSomething(int *pClientsReady)
 	XFD_COPYSET(&AllSockets, &LastSelectMask);
 #ifdef SMART_SCHEDULE
 	}
-	SmartScheduleIdle = TRUE;
+	SmartScheduleStopTimer ();
+
 #endif
 	BlockHandler((pointer)&wt, (pointer)&LastSelectMask);
 	if (NewOutputPending)
@@ -237,13 +238,7 @@ WaitForSomething(int *pClientsReady)
 	selecterr = GetErrno();
 	WakeupHandler(i, (pointer)&LastSelectMask);
 #ifdef SMART_SCHEDULE
-	if (i >= 0)
-	{
-	    SmartScheduleIdle = FALSE;
-	    SmartScheduleIdleCount = 0;
-	    if (SmartScheduleTimerStopped)
-		(void) SmartScheduleStartTimer ();
-	}
+	SmartScheduleStartTimer ();
 #endif
 	if (i <= 0) /* An error or timeout occurred */
 	{
diff --git a/os/utils.c b/os/utils.c
index 31cb0af..6fc1f7d 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1513,10 +1513,6 @@ XNFstrdup(const char *s)
 
 #ifdef SMART_SCHEDULE
 
-unsigned long	SmartScheduleIdleCount;
-Bool		SmartScheduleIdle;
-Bool		SmartScheduleTimerStopped;
-
 #ifdef SIGVTALRM
 #define SMART_SCHEDULE_POSSIBLE
 #endif
@@ -1526,7 +1522,7 @@ Bool		SmartScheduleTimerStopped;
 #define SMART_SCHEDULE_TIMER		ITIMER_REAL
 #endif
 
-static void
+void
 SmartScheduleStopTimer (void)
 {
 #ifdef SMART_SCHEDULE_POSSIBLE
@@ -1537,38 +1533,28 @@ SmartScheduleStopTimer (void)
     timer.it_value.tv_sec = 0;
     timer.it_value.tv_usec = 0;
     (void) setitimer (ITIMER_REAL, &timer, 0);
-    SmartScheduleTimerStopped = TRUE;
 #endif
 }
 
-Bool
+void
 SmartScheduleStartTimer (void)
 {
 #ifdef SMART_SCHEDULE_POSSIBLE
     struct itimerval	timer;
     
-    SmartScheduleTimerStopped = FALSE;
     timer.it_interval.tv_sec = 0;
     timer.it_interval.tv_usec = SmartScheduleInterval * 1000;
     timer.it_value.tv_sec = 0;
     timer.it_value.tv_usec = SmartScheduleInterval * 1000;
-    return setitimer (ITIMER_REAL, &timer, 0) >= 0;
+    setitimer (ITIMER_REAL, &timer, 0);
 #endif
-    return FALSE;
 }
 
 #ifdef SMART_SCHEDULE_POSSIBLE
 static void
 SmartScheduleTimer (int sig)
 {
-    int olderrno = errno;
-
     SmartScheduleTime += SmartScheduleInterval;
-    if (SmartScheduleIdle)
-    {
-	SmartScheduleStopTimer ();
-    }
-    errno = olderrno;
 }
 #endif
 
@@ -1592,14 +1578,6 @@ SmartScheduleInit (void)
 	perror ("sigaction for smart scheduler");
 	return FALSE;
     }
-    /* Set up the virtual timer */
-    if (!SmartScheduleStartTimer ())
-    {
-	perror ("scheduling timer");
-	return FALSE;
-    }
-    /* stop the timer and wait for WaitForSomething to start it */
-    SmartScheduleStopTimer ();
     return TRUE;
 #else
     return FALSE;
-- 
1.5.3.4

-- 
Ubuntu-devel-discuss mailing list
Ubuntu-devel-discuss@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/ubuntu-devel-discuss

Reply via email to