-Add the actual ProcSyncAwaitFence() dispatch func

-Add support for fence sync triggers.

Signed-off-by: James Jones <jajo...@nvidia.com>
---
 Xext/sync.c    |  183 ++++++++++++++++++++++++++++++++++++++++++++++----------
 Xext/syncsrv.h |    1 -
 2 files changed, 152 insertions(+), 32 deletions(-)

diff --git a/Xext/sync.c b/Xext/sync.c
index 8955a72..6fcdd72 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -147,6 +147,9 @@ SyncDeleteTriggerFromSyncObject(SyncTrigger *pTrigger)
 
        if (IsSystemCounter(pCounter))
            SyncComputeBracketValues(pCounter);
+    } else if (SYNC_FENCE == pTrigger->pSync->type) {
+       SyncFence* pFence = (SyncFence*) pTrigger->pSync;
+       pFence->funcs.DeleteTrigger(pTrigger);
     }
 }
 
@@ -180,23 +183,27 @@ SyncAddTriggerToSyncObject(SyncTrigger *pTrigger)
 
        if (IsSystemCounter(pCounter))
            SyncComputeBracketValues(pCounter);
+    } else if (SYNC_FENCE == pTrigger->pSync->type) {
+       SyncFence* pFence = (SyncFence*) pTrigger->pSync;
+       pFence->funcs.AddTrigger(pTrigger);
     }
 
     return Success;
 }
 
 
-/*  Below are four possible functions that can be plugged into
- *  pTrigger->CheckTrigger, corresponding to the four possible
- *  test-types.  These functions are called after the counter's
- *  value changes but are also passed the old counter value
- *  so they can inspect both the old and new values.
- *  (PositiveTransition and NegativeTransition need to see both
- *  pieces of information.)  These functions return the truth value
- *  of the trigger.
+/*  Below are five possible functions that can be plugged into
+ *  pTrigger->CheckTrigger for counter sync objects, corresponding to
+ *  the four possible test-types, and the one possible function that
+ *  can be plugged into pTrigger->CheckTrigger for fence sync objects.
+ *  These functions are called after the sync object's state changes
+ *  but are also passed the old state so they can inspect both the old
+ *  and new values.  (PositiveTransition and NegativeTransition need to
+ *  see both pieces of information.)  These functions return the truth
+ *  value of the trigger.
  *
- *  All of them include the condition pTrigger->pCounter == NULL.
- *  This is because the spec says that a trigger with a counter value
+ *  All of them include the condition pTrigger->pSync == NULL.
+ *  This is because the spec says that a trigger with a sync value
  *  of None is always TRUE.
  */
 
@@ -250,6 +257,16 @@ SyncCheckTriggerNegativeTransition(SyncTrigger *pTrigger, 
CARD64 oldval)
             XSyncValueLessOrEqual(pCounter->value, pTrigger->test_value)));
 }
 
+static Bool
+SyncCheckTriggerFence(SyncTrigger *pTrigger, CARD64 unused)
+{
+    SyncFence* pFence = (SyncFence*) pTrigger->pSync;
+    (void)unused;
+
+    return (pFence == NULL ||
+           pFence->funcs.CheckTriggered(pFence));
+}
+
 static int
 SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject,
                RESTYPE resType, Mask changes)
@@ -302,30 +319,38 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, 
XID syncObject,
 
     if (changes & XSyncCATestType)
     {
-       if (pTrigger->test_type != XSyncPositiveTransition &&
-           pTrigger->test_type != XSyncNegativeTransition &&
-           pTrigger->test_type != XSyncPositiveComparison &&
-           pTrigger->test_type != XSyncNegativeComparison)
+
+       if (SYNC_FENCE == pSync->type)
        {
-           client->errorValue = pTrigger->test_type;
-           return BadValue;
+           pTrigger->CheckTrigger = SyncCheckTriggerFence;
        }
-       /* select appropriate CheckTrigger function */
-
-       switch (pTrigger->test_type)
+       else
        {
-       case XSyncPositiveTransition:
-           pTrigger->CheckTrigger = SyncCheckTriggerPositiveTransition;
-           break;
-       case XSyncNegativeTransition:
-           pTrigger->CheckTrigger = SyncCheckTriggerNegativeTransition;
-           break;
-       case XSyncPositiveComparison:
-           pTrigger->CheckTrigger = SyncCheckTriggerPositiveComparison;
-           break;
-       case XSyncNegativeComparison:
-           pTrigger->CheckTrigger = SyncCheckTriggerNegativeComparison;
-           break;
+           if (pTrigger->test_type != XSyncPositiveTransition &&
+               pTrigger->test_type != XSyncNegativeTransition &&
+               pTrigger->test_type != XSyncPositiveComparison &&
+               pTrigger->test_type != XSyncNegativeComparison)
+           {
+               client->errorValue = pTrigger->test_type;
+               return BadValue;
+           }
+           /* select appropriate CheckTrigger function */
+
+           switch (pTrigger->test_type)
+           {
+           case XSyncPositiveTransition:
+               pTrigger->CheckTrigger = SyncCheckTriggerPositiveTransition;
+               break;
+           case XSyncNegativeTransition:
+               pTrigger->CheckTrigger = SyncCheckTriggerNegativeTransition;
+               break;
+           case XSyncPositiveComparison:
+               pTrigger->CheckTrigger = SyncCheckTriggerPositiveComparison;
+               break;
+           case XSyncNegativeComparison:
+               pTrigger->CheckTrigger = SyncCheckTriggerNegativeComparison;
+               break;
+           }
        }
     }
 
@@ -2019,6 +2044,89 @@ ProcSyncQueryFence(ClientPtr client)
     return client->noClientException;
 }
 
+static int
+ProcSyncAwaitFence(ClientPtr client)
+{
+    REQUEST(xSyncAwaitFenceReq);
+    SyncAwaitUnion *pAwaitUnion;
+    SyncAwait *pAwait;
+    /* Use CARD32 rather than XSyncFence because XIDs are hard-coded to
+     * CARD32 in protocol definitions */
+    CARD32 *pProtocolFences;
+    int status;
+    int len;
+    int items;
+    int i;
+
+    REQUEST_AT_LEAST_SIZE(xSyncAwaitFenceReq);
+
+    len = client->req_len << 2;
+    len -= sz_xSyncAwaitFenceReq;
+    items = len / sizeof(CARD32);
+
+    if (items * sizeof(CARD32) != len)
+    {
+       return BadLength;
+    }
+    if (items == 0)
+    {
+       client->errorValue = items; /* XXX protocol change */
+       return BadValue;
+    }
+
+    if (!(pAwaitUnion = SyncAwaitPrologue(client, items)))
+       return BadAlloc;
+
+    /* don't need to do any more memory allocation for this request! */
+
+    pProtocolFences = (CARD32 *) & stuff[1];
+
+    pAwait = &(pAwaitUnion+1)->await; /* skip over header */
+    for (i = 0; i < items; i++, pProtocolFences++, pAwait++)
+    {
+       if (*pProtocolFences == None) /* XXX protocol change */
+       {
+           /*  this should take care of removing any triggers created by
+            *  this request that have already been registered on sync objects
+            */
+           FreeResource(pAwaitUnion->header.delete_id, RT_NONE);
+           client->errorValue = *pProtocolFences;
+           return SyncErrorBase + XSyncBadCounter;
+       }
+
+       pAwait->trigger.pSync = NULL;
+       /* Provide acceptable values for these unused fields to
+        * satisfy SyncInitTrigger's validation logic
+        */
+       pAwait->trigger.value_type = XSyncAbsolute;
+       XSyncIntToValue(&pAwait->trigger.wait_value, 0);
+       pAwait->trigger.test_type = 0;
+
+       status = SyncInitTrigger(client, &pAwait->trigger,
+                                *pProtocolFences, RTFence,
+                                XSyncCAAllTrigger);
+       if (status != Success)
+       {
+           /*  this should take care of removing any triggers created by
+            *  this request that have already been registered on sync objects
+            */
+           FreeResource(pAwaitUnion->header.delete_id, RT_NONE);
+           return status;
+       }
+       /* this is not a mistake -- same function works for both cases */
+       pAwait->trigger.TriggerFired = SyncAwaitTriggerFired;
+       pAwait->trigger.CounterDestroyed = SyncAwaitTriggerFired;
+       /* event_threshold is unused for fence syncs */
+       XSyncIntToValue(&pAwait->event_threshold, 0);
+       pAwait->pHeader = &pAwaitUnion->header;
+       pAwaitUnion->header.num_waitconditions++;
+    }
+
+    SyncAwaitEpilogue(client, items, pAwaitUnion);
+
+    return client->noClientException;
+}
+
 /*
  * ** Given an extension request, call the appropriate request procedure
  */
@@ -2322,6 +2430,19 @@ SProcSyncQueryFence(ClientPtr client)
 }
 
 static int
+SProcSyncAwaitFence(ClientPtr client)
+{
+    REQUEST(xSyncAwaitFenceReq);
+    char   n;
+
+    swaps(&stuff->length, n);
+    REQUEST_AT_LEAST_SIZE(xSyncAwaitFenceReq);
+    SwapRestL(stuff);
+
+    return ProcSyncAwaitFence(client);
+}
+
+static int
 SProcSyncDispatch(ClientPtr client)
 {
     REQUEST(xReq);
diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h
index aa7dfb9..7ca1fba 100644
--- a/Xext/syncsrv.h
+++ b/Xext/syncsrv.h
@@ -117,7 +117,6 @@ typedef union {
     SyncAwait      await;
 } SyncAwaitUnion;
 
-
 extern pointer SyncCreateSystemCounter(
     char *     /* name */,
     CARD64     /* inital_value */,
-- 
1.7.1

_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to