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

xorg-server: Changes to 'debian-lenny'



 Xext/sync.c      |   51 +++++++++++++++++++++++++++++++++++++++++----------
 debian/changelog |    2 ++
 2 files changed, 43 insertions(+), 10 deletions(-)

New commits:
commit 8414790e71e4e0a603f1937239394fad57ce22a7
Author: Julien Cristau <jcristau@debian.org>
Date:   Tue May 26 00:02:14 2009 +0200

    Update changelog

diff --git a/debian/changelog b/debian/changelog
index 56acd25..4426a46 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -3,6 +3,8 @@ xorg-server (2:1.4.2-10.lenny2) UNRELEASED; urgency=low
   * Revert change from -10.lenny1.  If both PCI and fb drivers are loaded, the
     server falls over, so the workaround doesn't work, and seems to break
     other setups...  This closes: #527058, and reopens #488669.
+  * Cherry-pick patch from upstream to fix wakeup storm in the idletime xsync
+    counter.
 
  -- Julien Cristau <jcristau@debian.org>  Fri, 22 May 2009 15:15:16 +0200
 

commit 4b6a55a67c2722568ce1ca8ad11af29a4aa8b36c
Author: Adam Jackson <ajax@redhat.com>
Date:   Wed Dec 10 16:13:20 2008 -0500

    xsync: Fix wakeup storm in idletime counter.
    
    Wakeup scheduling only considered the threshold values, and not whether
    the trigger was edge or level.
    
    See also:
    https://bugzilla.redhat.com/show_bug.cgi?id=474586
    http://svn.gnome.org/viewvc/gnome-screensaver/trunk/src/test-idle-ext.c?view=markup
    (cherry picked from commit 1f4fb0225b278d1cf4145aebeb0bdd23dc8f62d5)
    (cherry picked from commit ca56d764d2be28c64fe15c9e37d534ef00117ad2)

diff --git a/Xext/sync.c b/Xext/sync.c
index d9b6a9f..6ef0dac 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -2533,7 +2533,7 @@ SyncInitServerTime(void)
  * IDLETIME implementation
  */
 
-static pointer IdleTimeCounter;
+static SyncCounter *IdleTimeCounter;
 static XSyncValue *pIdleTimeValueLess;
 static XSyncValue *pIdleTimeValueGreater;
 
@@ -2545,38 +2545,69 @@ IdleTimeQueryValue (pointer pCounter, CARD64 *pValue_return)
 }
 
 static void
-IdleTimeBlockHandler (pointer env,
-                      struct timeval **wt,
-                      pointer LastSelectMask)
+IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask)
 {
-    XSyncValue idle;
+    XSyncValue idle, old_idle;
+    SyncTriggerList *list = IdleTimeCounter->pTriglist;
+    SyncTrigger *trig;
 
     if (!pIdleTimeValueLess && !pIdleTimeValueGreater)
 	return;
 
+    old_idle = IdleTimeCounter->value;
     IdleTimeQueryValue (NULL, &idle);
+    IdleTimeCounter->value = idle; /* push, so CheckTrigger works */
 
     if (pIdleTimeValueLess &&
         XSyncValueLessOrEqual (idle, *pIdleTimeValueLess))
     {
-	AdjustWaitForDelay (wt, 0);
+	/*
+	 * We've been idle for less than the threshold value, and someone
+	 * wants to know about that, but now we need to know whether they
+	 * want level or edge trigger.  Check the trigger list against the
+	 * current idle time, and if any succeed, bomb out of select()
+	 * immediately so we can reschedule.
+	 */
+
+	for (list = IdleTimeCounter->pTriglist; list; list = list->next) {
+	    trig = list->pTrigger;
+	    if (trig->CheckTrigger(trig, old_idle)) {
+		AdjustWaitForDelay(wt, 0);
+		break;
+	    }
+	}
     }
     else if (pIdleTimeValueGreater)
     {
-	unsigned long timeout = 0;
+	/*
+	 * There's a threshold in the positive direction.  If we've been
+	 * idle less than it, schedule a wakeup for sometime in the future.
+	 * If we've been idle more than it, and someone wants to know about
+	 * that level-triggered, schedule an immediate wakeup.
+	 */
+	unsigned long timeout = -1;
 
-	if (XSyncValueLessThan (idle, *pIdleTimeValueGreater))
-	{
+	if (XSyncValueLessThan (idle, *pIdleTimeValueGreater)) {
 	    XSyncValue value;
 	    Bool overflow;
 
 	    XSyncValueSubtract (&value, *pIdleTimeValueGreater,
 	                        idle, &overflow);
-	    timeout = XSyncValueLow32 (value);
+	    timeout = min(timeout, XSyncValueLow32 (value));
+	} else {
+	    for (list = IdleTimeCounter->pTriglist; list; list = list->next) {
+		trig = list->pTrigger;
+		if (trig->CheckTrigger(trig, old_idle)) {
+		    timeout = min(timeout, 0);
+		    break;
+		}
+	    }
 	}
 
 	AdjustWaitForDelay (wt, timeout);
     }
+
+    IdleTimeCounter->value = old_idle; /* pop */
 }
 
 static void


Reply to: