Add XSyncAwaitFence() handler
-Add the actual ProcSyncAwaitFence() dispatch func -Add support for fence sync triggers. Signed-off-by: James Jones <jajones@nvidia.com> Reviewed-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
parent
397dfd9f87
commit
9c0c7cc9a7
141
Xext/sync.c
141
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)
|
||||
|
@ -301,6 +318,13 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject,
|
|||
}
|
||||
|
||||
if (changes & XSyncCATestType)
|
||||
{
|
||||
|
||||
if (SYNC_FENCE == pSync->type)
|
||||
{
|
||||
pTrigger->CheckTrigger = SyncCheckTriggerFence;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pTrigger->test_type != XSyncPositiveTransition &&
|
||||
pTrigger->test_type != XSyncNegativeTransition &&
|
||||
|
@ -328,6 +352,7 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject,
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changes & (XSyncCAValueType | XSyncCAValue))
|
||||
{
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -2321,6 +2429,19 @@ SProcSyncQueryFence(ClientPtr client)
|
|||
return ProcSyncQueryFence(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)
|
||||
{
|
||||
|
|
|
@ -117,7 +117,6 @@ typedef union {
|
|||
SyncAwait await;
|
||||
} SyncAwaitUnion;
|
||||
|
||||
|
||||
extern pointer SyncCreateSystemCounter(
|
||||
char * /* name */,
|
||||
CARD64 /* inital_value */,
|
||||
|
|
Loading…
Reference in New Issue
Block a user