Xext/sync.c | 51 +++++++++++++++++++++++++++++++++++++++++---------- debian/changelog | 2 ++ 2 files changed, 43 insertions(+), 10 deletions(-)
New commits: commit 8414790e71e4e0a603f1937239394fad57ce22a7 Author: Julien Cristau <jcris...@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 <jcris...@debian.org> Fri, 22 May 2009 15:15:16 +0200 commit 4b6a55a67c2722568ce1ca8ad11af29a4aa8b36c Author: Adam Jackson <a...@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 -- To UNSUBSCRIBE, email to debian-x-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org