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
185
Xext/sync.c
185
Xext/sync.c
|
@ -147,6 +147,9 @@ SyncDeleteTriggerFromSyncObject(SyncTrigger *pTrigger)
|
||||||
|
|
||||||
if (IsSystemCounter(pCounter))
|
if (IsSystemCounter(pCounter))
|
||||||
SyncComputeBracketValues(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))
|
if (IsSystemCounter(pCounter))
|
||||||
SyncComputeBracketValues(pCounter);
|
SyncComputeBracketValues(pCounter);
|
||||||
|
} else if (SYNC_FENCE == pTrigger->pSync->type) {
|
||||||
|
SyncFence* pFence = (SyncFence*) pTrigger->pSync;
|
||||||
|
pFence->funcs.AddTrigger(pTrigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Below are four possible functions that can be plugged into
|
/* Below are five possible functions that can be plugged into
|
||||||
* pTrigger->CheckTrigger, corresponding to the four possible
|
* pTrigger->CheckTrigger for counter sync objects, corresponding to
|
||||||
* test-types. These functions are called after the counter's
|
* the four possible test-types, and the one possible function that
|
||||||
* value changes but are also passed the old counter value
|
* can be plugged into pTrigger->CheckTrigger for fence sync objects.
|
||||||
* so they can inspect both the old and new values.
|
* These functions are called after the sync object's state changes
|
||||||
* (PositiveTransition and NegativeTransition need to see both
|
* but are also passed the old state so they can inspect both the old
|
||||||
* pieces of information.) These functions return the truth value
|
* and new values. (PositiveTransition and NegativeTransition need to
|
||||||
* of the trigger.
|
* see both pieces of information.) These functions return the truth
|
||||||
|
* value of the trigger.
|
||||||
*
|
*
|
||||||
* All of them include the condition pTrigger->pCounter == NULL.
|
* All of them include the condition pTrigger->pSync == NULL.
|
||||||
* This is because the spec says that a trigger with a counter value
|
* This is because the spec says that a trigger with a sync value
|
||||||
* of None is always TRUE.
|
* of None is always TRUE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -250,6 +257,16 @@ SyncCheckTriggerNegativeTransition(SyncTrigger *pTrigger, CARD64 oldval)
|
||||||
XSyncValueLessOrEqual(pCounter->value, pTrigger->test_value)));
|
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
|
static int
|
||||||
SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject,
|
SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject,
|
||||||
RESTYPE resType, Mask changes)
|
RESTYPE resType, Mask changes)
|
||||||
|
@ -302,30 +319,38 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject,
|
||||||
|
|
||||||
if (changes & XSyncCATestType)
|
if (changes & XSyncCATestType)
|
||||||
{
|
{
|
||||||
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)
|
if (SYNC_FENCE == pSync->type)
|
||||||
{
|
{
|
||||||
case XSyncPositiveTransition:
|
pTrigger->CheckTrigger = SyncCheckTriggerFence;
|
||||||
pTrigger->CheckTrigger = SyncCheckTriggerPositiveTransition;
|
}
|
||||||
break;
|
else
|
||||||
case XSyncNegativeTransition:
|
{
|
||||||
pTrigger->CheckTrigger = SyncCheckTriggerNegativeTransition;
|
if (pTrigger->test_type != XSyncPositiveTransition &&
|
||||||
break;
|
pTrigger->test_type != XSyncNegativeTransition &&
|
||||||
case XSyncPositiveComparison:
|
pTrigger->test_type != XSyncPositiveComparison &&
|
||||||
pTrigger->CheckTrigger = SyncCheckTriggerPositiveComparison;
|
pTrigger->test_type != XSyncNegativeComparison)
|
||||||
break;
|
{
|
||||||
case XSyncNegativeComparison:
|
client->errorValue = pTrigger->test_type;
|
||||||
pTrigger->CheckTrigger = SyncCheckTriggerNegativeComparison;
|
return BadValue;
|
||||||
break;
|
}
|
||||||
|
/* 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;
|
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
|
* ** Given an extension request, call the appropriate request procedure
|
||||||
*/
|
*/
|
||||||
|
@ -2321,6 +2429,19 @@ SProcSyncQueryFence(ClientPtr client)
|
||||||
return ProcSyncQueryFence(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
|
static int
|
||||||
SProcSyncDispatch(ClientPtr client)
|
SProcSyncDispatch(ClientPtr client)
|
||||||
{
|
{
|
||||||
|
|
|
@ -117,7 +117,6 @@ typedef union {
|
||||||
SyncAwait await;
|
SyncAwait await;
|
||||||
} SyncAwaitUnion;
|
} SyncAwaitUnion;
|
||||||
|
|
||||||
|
|
||||||
extern pointer SyncCreateSystemCounter(
|
extern pointer SyncCreateSystemCounter(
|
||||||
char * /* name */,
|
char * /* name */,
|
||||||
CARD64 /* inital_value */,
|
CARD64 /* inital_value */,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user