diff -r f9b973ecc909 -r 24ca414edbff open-src/xserver/xorg/xsync-idletime-counter.patch --- a/open-src/xserver/xorg/xsync-idletime-counter.patch Thu May 14 20:00:54 2009 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,111 +0,0 @@ -From ca56d764d2be28c64fe15c9e37d534ef00117ad2 Mon Sep 17 00:00:00 2001 -From: Adam Jackson -Date: Wed, 10 Dec 2008 16:13:20 -0500 -Subject: [PATCH] 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) ---- - Xext/sync.c | 51 +++++++++++++++++++++++++++++++++++++++++---------- - 1 files changed, 41 insertions(+), 10 deletions(-) - -diff --git a/Xext/sync.c b/Xext/sync.c -index 63f6fa2..1b37366 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 --- -1.5.6.5 -