File xorg-x11-server-bnc472046-Fixed-SYNC-extension-trigger-BlockHandler-test.patch of Package xorg-x11-server
From 6dbae4f4841ddfb70d6f2a973431f34d2b3cc4c0 Mon Sep 17 00:00:00 2001
From: Egbert Eich <eich@freedesktop.org>
Date: Mon, 23 Mar 2009 12:58:28 +0100
Subject: [PATCH] Fixed SYNC extension trigger BlockHandler test.
* Reworked ComputeBracketValues():
+ Removed 'startOver' flag: we always seem to want to start
over, there doesn't seem to be a reason why we should keep the old
bracket values, moreover when this flag was set the semantics of
setting the bracket values for the selected sync counter were flawed
anyhow:
the bracket whose value hadn't changed (if the other one did) was simply
deleted.
+ Rewrote the bracket value calculation for Postitive/NegativeTransition:
the calulation didn't cover all possible cases and was flawed anyhow.
* Reworked previous patch to IdleTimeBlockHandler()
(commit: 1f4fb022)
+ Simplified code.
+ Modified heuristics:
pIdleTimeValueLess does not exclude pIdleTimeValueGreater: if no wakeup
is scheduled for the former one check if there is one for the latter.
+ If no immediate wakeup is scheduled at all find schedule a wakeup for
the next time an idle counter might trigger, do not wait for the latest
idle counter to trigger.
This fixes a problem introduced with commit 1f4fb022 where an idle counter
expires unnoticed.
---
Xext/sync.c | 179 +++++++++++++++++++++++++++++++----------------------------
1 files changed, 94 insertions(+), 85 deletions(-)
diff --git a/Xext/sync.c b/Xext/sync.c
index adb7324..4c03e06 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -97,7 +97,7 @@ static SyncCounter **SysCounterList = NULL;
#define XSyncCAAllTrigger \
(XSyncCACounter | XSyncCAValueType | XSyncCAValue | XSyncCATestType)
-static void SyncComputeBracketValues(SyncCounter *, Bool);
+static void SyncComputeBracketValues(SyncCounter *);
static void SyncInitServerTime(void);
@@ -170,7 +170,7 @@ SyncDeleteTriggerFromCounter(SyncTrigger *pTrigger)
}
if (IsSystemCounter(pTrigger->pCounter))
- SyncComputeBracketValues(pTrigger->pCounter, /*startOver*/ TRUE);
+ SyncComputeBracketValues(pTrigger->pCounter);
}
@@ -197,7 +197,7 @@ SyncAddTriggerToCounter(SyncTrigger *pTrigger)
pTrigger->pCounter->pTriglist = pCur;
if (IsSystemCounter(pTrigger->pCounter))
- SyncComputeBracketValues(pTrigger->pCounter, /*startOver*/ TRUE);
+ SyncComputeBracketValues(pTrigger->pCounter);
return Success;
}
@@ -354,7 +354,7 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XSyncCounter counter,
}
else if (IsSystemCounter(pCounter))
{
- SyncComputeBracketValues(pCounter, /*startOver*/ TRUE);
+ SyncComputeBracketValues(pCounter);
}
return Success;
@@ -643,13 +643,14 @@ SyncChangeCounter(SyncCounter *pCounter, CARD64 newval)
for (ptl = pCounter->pTriglist; ptl; ptl = pnext)
{
pnext = ptl->next;
- if ((*ptl->pTrigger->CheckTrigger)(ptl->pTrigger, oldval))
+ if ((*ptl->pTrigger->CheckTrigger)(ptl->pTrigger, oldval)) {
(*ptl->pTrigger->TriggerFired)(ptl->pTrigger);
+ }
}
if (IsSystemCounter(pCounter))
{
- SyncComputeBracketValues(pCounter, /* startOver */ FALSE);
+ SyncComputeBracketValues(pCounter);
}
}
@@ -916,7 +917,7 @@ SyncDestroySystemCounter(pointer pSysCounter)
}
static void
-SyncComputeBracketValues(SyncCounter *pCounter, Bool startOver)
+SyncComputeBracketValues(SyncCounter *pCounter)
{
SyncTriggerList *pCur;
SyncTrigger *pTrigger;
@@ -933,60 +934,51 @@ SyncComputeBracketValues(SyncCounter *pCounter, Bool startOver)
if (ct == XSyncCounterNeverChanges)
return;
- if (startOver)
- {
- XSyncMaxValue(&psci->bracket_greater);
- XSyncMinValue(&psci->bracket_less);
- }
+ XSyncMaxValue(&psci->bracket_greater);
+ XSyncMinValue(&psci->bracket_less);
+
for (pCur = pCounter->pTriglist; pCur; pCur = pCur->next)
{
pTrigger = pCur->pTrigger;
-
- if (pTrigger->test_type == XSyncPositiveComparison &&
- ct != XSyncCounterNeverIncreases)
- {
- if (XSyncValueLessThan(pCounter->value, pTrigger->test_value) &&
- XSyncValueLessThan(pTrigger->test_value,
- psci->bracket_greater))
- {
- psci->bracket_greater = pTrigger->test_value;
- pnewgtval = &psci->bracket_greater;
- }
- }
- else if (pTrigger->test_type == XSyncNegativeComparison &&
- ct != XSyncCounterNeverDecreases)
- {
- if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value) &&
- XSyncValueGreaterThan(pTrigger->test_value,
- psci->bracket_less))
- {
- psci->bracket_less = pTrigger->test_value;
- pnewltval = &psci->bracket_less;
- }
- }
- else if ( (pTrigger->test_type == XSyncPositiveTransition &&
- ct != XSyncCounterNeverIncreases)
- ||
- (pTrigger->test_type == XSyncNegativeTransition &&
- ct != XSyncCounterNeverDecreases)
+
+ if ( ( (pTrigger->test_type == XSyncPositiveComparison)
+ && ( XSyncValueGreaterOrEqual(pCounter->value, pTrigger->test_value)
+ || (ct != XSyncCounterNeverIncreases
+ && XSyncValueLessThan(pCounter->value, pTrigger->test_value))
+ )
+ )
+ || ((pTrigger->test_type == XSyncPositiveTransition)
+ && ( ( ct != XSyncCounterNeverDecreases
+ && XSyncValueGreaterOrEqual(pCounter->value, pTrigger->test_value))
+ || ( ct != XSyncCounterNeverIncreases
+ && XSyncValueLessThan(pCounter->value, pTrigger->test_value))
+ )
)
- {
- if (XSyncValueLessThan(pCounter->value, pTrigger->test_value))
- {
- if (XSyncValueLessThan(pTrigger->test_value,
- psci->bracket_greater))
- {
- psci->bracket_greater = pTrigger->test_value;
- pnewgtval = &psci->bracket_greater;
- }
- else
- if (XSyncValueGreaterThan(pTrigger->test_value,
- psci->bracket_less))
- {
- psci->bracket_less = pTrigger->test_value;
- pnewltval = &psci->bracket_less;
+ ) {
+ if (XSyncValueLessThan(pTrigger->test_value,
+ psci->bracket_greater)) {
+ psci->bracket_greater = pTrigger->test_value;
+ pnewgtval = &psci->bracket_greater;
}
+ } else if ( ( (pTrigger->test_type == XSyncNegativeComparison)
+ && ( XSyncValueLessOrEqual(pCounter->value, pTrigger->test_value)
+ || (ct != XSyncCounterNeverDecreases
+ && XSyncValueGreaterThan(pCounter->value, pTrigger->test_value))
+ )
+ )
+ || ((pTrigger->test_type == XSyncNegativeTransition)
+ && ( ( ct != XSyncCounterNeverDecreases
+ && XSyncValueGreaterOrEqual(pCounter->value, pTrigger->test_value))
+ || ( ct != XSyncCounterNeverIncreases
+ && XSyncValueLessThan(pCounter->value, pTrigger->test_value))
+ )
+ )
+ ) {
+ if (XSyncValueGreaterThan(pTrigger->test_value,
+ psci->bracket_less)) {
+ psci->bracket_less = pTrigger->test_value;
+ pnewltval = &psci->bracket_less;
}
}
} /* end for each trigger */
@@ -2291,11 +2283,17 @@ IdleTimeQueryValue (pointer pCounter, CARD64 *pValue_return)
}
static void
-IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask)
-{
- XSyncValue idle, old_idle;
- SyncTriggerList *list = IdleTimeCounter->pTriglist;
- SyncTrigger *trig;
+IdleTimeBlockHandler (pointer env,
+ struct timeval **wt,
+ pointer LastSelectMask)
+{
+ XSyncValue idle, old_idle;
+ SyncTriggerList *list = IdleTimeCounter->pTriglist;
+ SyncTrigger *trig;
+ unsigned long timeout = -1;
+ XSyncValue value;
+ Bool overflow;
+
if (!pIdleTimeValueLess && !pIdleTimeValueGreater)
return;
@@ -2313,46 +2311,57 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask)
* 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.
+ * NOTE: we need to check trigger because the idle timer can go
+ * both ways (XSyncCounterUnrestricted) so that we need to set
+ * pIdleTimeValueLess in ComputeBracketValues() in the edge
+ * triggered case even if the idle timer is already less.
*/
-
- for (list = IdleTimeCounter->pTriglist; list; list = list->next) {
+ for (list = IdleTimeCounter->pTriglist; list; list = list->next) {
trig = list->pTrigger;
if (trig->CheckTrigger(trig, old_idle)) {
- AdjustWaitForDelay(wt, 0);
- break;
+ AdjustWaitForDelay(wt, 0);
+ IdleTimeCounter->value = old_idle; /* pop */
+ return;
}
}
}
- else if (pIdleTimeValueGreater)
+ if (pIdleTimeValueGreater)
{
- /*
- * 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)) {
- XSyncValue value;
- Bool overflow;
+ /*
+ * There's a threshold in the positive direction.
+ * If we've been idle more than it, and someone wants to know about
+ * that level-triggered, schedule an immediate wakeup.
+ * NOTE: we need to check trigger because the idle timer can go
+ * both ways (XSyncCounterUnrestricted) so that we need to set
+ * pIdleTimeValueGreater in ComputeBracketValues() in the edge
+ * triggered case even if the idle timer is already greater.
+ */
- XSyncValueSubtract (&value, *pIdleTimeValueGreater,
- idle, &overflow);
- timeout = min(timeout, XSyncValueLow32 (value));
- } else {
+ if (XSyncValueGreaterOrEqual (idle, *pIdleTimeValueGreater)) {
for (list = IdleTimeCounter->pTriglist; list; list = list->next) {
- trig = list->pTrigger;
+ trig = list->pTrigger;
if (trig->CheckTrigger(trig, old_idle)) {
- timeout = min(timeout, 0);
- break;
+ AdjustWaitForDelay (wt, 0);
+ IdleTimeCounter->value = old_idle; /* pop */
+ return;
}
}
}
-
- AdjustWaitForDelay (wt, timeout);
}
+ /*
+ * If we don't have to wake up immediately we schedule a wakeup for the
+ * next time a trigger expires.
+ */
+ for (list = IdleTimeCounter->pTriglist; list; list = list->next) {
+ trig = list->pTrigger;
+ if (XSyncValueLessThan (idle, trig->test_value)) {
+ XSyncValueSubtract (&value, trig->test_value,
+ idle, &overflow);
+ timeout = min(timeout,XSyncValueLow32 (value));
+ }
+ }
+ AdjustWaitForDelay (wt, timeout);
IdleTimeCounter->value = old_idle; /* pop */
}
--
1.5.2.4