xserver: Branch 'master' - 6 commits

Adam Jackson ajax at kemper.freedesktop.org
Wed Sep 20 17:23:21 UTC 2017


 Xext/sync.c                          |  302 ++++++++++++++++------------------
 Xext/syncsrv.h                       |   23 +-
 hw/meson.build                       |    4 
 hw/vfb/meson.build                   |    2 
 include/misc.h                       |   29 +++
 meson.build                          |    1 
 meson_options.txt                    |    2 
 miext/sync/misync.c                  |    5 
 miext/sync/misyncstr.h               |   22 +-
 present/present_fence.c              |    2 
 test/meson.build                     |   26 ++
 test/scripts/xephyr-glamor-piglit.sh |    7 
 test/scripts/xvfb-piglit.sh          |    7 
 test/simple-xinit.c                  |    3 
 test/sync/meson.build                |    9 +
 test/sync/sync.c                     |  304 +++++++++++++++++++++++++++++++++++
 16 files changed, 557 insertions(+), 191 deletions(-)

New commits:
commit 294670682120c65001b36369d6395003704f4ac1
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Sep 18 17:34:33 2017 -0700

    sync: Clean up a bit of header formatting.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/miext/sync/misyncstr.h b/miext/sync/misyncstr.h
index 084ca4c82..2eab2aa57 100644
--- a/miext/sync/misyncstr.h
+++ b/miext/sync/misyncstr.h
@@ -49,7 +49,7 @@ typedef struct _SyncObject {
 typedef struct _SyncCounter {
     SyncObject sync;            /* Common sync object data */
     int64_t value;              /* counter value */
-    struct _SysCounterInfo *pSysCounterInfo;    /* NULL if not a system counter */
+    struct _SysCounterInfo *pSysCounterInfo; /* NULL if not a system counter */
 } SyncCounter;
 
 struct _SyncFence {
@@ -66,13 +66,10 @@ struct _SyncTrigger {
     unsigned int value_type;    /* Absolute or Relative */
     unsigned int test_type;     /* transition or Comparision type */
     int64_t test_value;         /* trigger event threshold value */
-    Bool (*CheckTrigger) (struct _SyncTrigger * /*pTrigger */ ,
-                          int64_t        /*newval */
-        );
-    void (*TriggerFired) (struct _SyncTrigger * /*pTrigger */
-        );
-    void (*CounterDestroyed) (struct _SyncTrigger *     /*pTrigger */
-        );
+    Bool (*CheckTrigger)(struct _SyncTrigger *pTrigger,
+                         int64_t newval);
+    void (*TriggerFired)(struct _SyncTrigger *pTrigger);
+    void (*CounterDestroyed)(struct _SyncTrigger *pTrigger);
 };
 
 typedef struct _SyncTriggerList {
commit e0f872207aa203adb85e825c311ed50fe3a3af60
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Sep 18 17:34:32 2017 -0700

    sync: Convert from "CARD64" to int64_t.
    
    The extension was using the name CARD64 to represent 64-bit values,
    with a #define from CARD64 to XSyncValue, a struct with a pair of
    32-bit values representing a signed 64-bit value.  This interfered
    with protocol headers using CARD64 to try to actually store a
    uint64_t.  Now that stdint.h exists, let's just use that here,
    instead.
    
    v2: Fix alarm delta changes.
    v3: Do the potentially overflowing math as uint and convert to int
        afterward, out of C spec paranoia.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/Xext/sync.c b/Xext/sync.c
index a8db0ec22..822c205a7 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -237,7 +237,7 @@ SyncAddTriggerToSyncObject(SyncTrigger * pTrigger)
  */
 
 static Bool
-SyncCheckTriggerPositiveComparison(SyncTrigger * pTrigger, CARD64 oldval)
+SyncCheckTriggerPositiveComparison(SyncTrigger * pTrigger, int64_t oldval)
 {
     SyncCounter *pCounter;
 
@@ -248,12 +248,11 @@ SyncCheckTriggerPositiveComparison(SyncTrigger * pTrigger, CARD64 oldval)
 
     pCounter = (SyncCounter *) pTrigger->pSync;
 
-    return (pCounter == NULL ||
-            XSyncValueGreaterOrEqual(pCounter->value, pTrigger->test_value));
+    return pCounter == NULL || pCounter->value >= pTrigger->test_value;
 }
 
 static Bool
-SyncCheckTriggerNegativeComparison(SyncTrigger * pTrigger, CARD64 oldval)
+SyncCheckTriggerNegativeComparison(SyncTrigger * pTrigger, int64_t oldval)
 {
     SyncCounter *pCounter;
 
@@ -264,12 +263,11 @@ SyncCheckTriggerNegativeComparison(SyncTrigger * pTrigger, CARD64 oldval)
 
     pCounter = (SyncCounter *) pTrigger->pSync;
 
-    return (pCounter == NULL ||
-            XSyncValueLessOrEqual(pCounter->value, pTrigger->test_value));
+    return pCounter == NULL || pCounter->value <= pTrigger->test_value;
 }
 
 static Bool
-SyncCheckTriggerPositiveTransition(SyncTrigger * pTrigger, CARD64 oldval)
+SyncCheckTriggerPositiveTransition(SyncTrigger * pTrigger, int64_t oldval)
 {
     SyncCounter *pCounter;
 
@@ -281,12 +279,12 @@ SyncCheckTriggerPositiveTransition(SyncTrigger * pTrigger, CARD64 oldval)
     pCounter = (SyncCounter *) pTrigger->pSync;
 
     return (pCounter == NULL ||
-            (XSyncValueLessThan(oldval, pTrigger->test_value) &&
-             XSyncValueGreaterOrEqual(pCounter->value, pTrigger->test_value)));
+            (oldval < pTrigger->test_value &&
+             pCounter->value >= pTrigger->test_value));
 }
 
 static Bool
-SyncCheckTriggerNegativeTransition(SyncTrigger * pTrigger, CARD64 oldval)
+SyncCheckTriggerNegativeTransition(SyncTrigger * pTrigger, int64_t oldval)
 {
     SyncCounter *pCounter;
 
@@ -298,12 +296,12 @@ SyncCheckTriggerNegativeTransition(SyncTrigger * pTrigger, CARD64 oldval)
     pCounter = (SyncCounter *) pTrigger->pSync;
 
     return (pCounter == NULL ||
-            (XSyncValueGreaterThan(oldval, pTrigger->test_value) &&
-             XSyncValueLessOrEqual(pCounter->value, pTrigger->test_value)));
+            (oldval > pTrigger->test_value &&
+             pCounter->value <= pTrigger->test_value));
 }
 
 static Bool
-SyncCheckTriggerFence(SyncTrigger * pTrigger, CARD64 unused)
+SyncCheckTriggerFence(SyncTrigger * pTrigger, int64_t unused)
 {
     SyncFence *pFence = (SyncFence *) pTrigger->pSync;
 
@@ -389,16 +387,15 @@ SyncInitTrigger(ClientPtr client, SyncTrigger * pTrigger, XID syncObject,
         if (pTrigger->value_type == XSyncAbsolute)
             pTrigger->test_value = pTrigger->wait_value;
         else {                  /* relative */
-
             Bool overflow;
 
             if (pCounter == NULL)
                 return BadMatch;
 
-            XSyncValueAdd(&pTrigger->test_value, pCounter->value,
-                          pTrigger->wait_value, &overflow);
+            overflow = checked_int64_add(&pTrigger->test_value,
+                                         pCounter->value, pTrigger->wait_value);
             if (overflow) {
-                client->errorValue = XSyncValueHigh32(pTrigger->wait_value);
+                client->errorValue = pTrigger->wait_value >> 32;
                 return BadValue;
             }
         }
@@ -441,15 +438,15 @@ SyncSendAlarmNotifyEvents(SyncAlarm * pAlarm)
         .type = SyncEventBase + XSyncAlarmNotify,
         .kind = XSyncAlarmNotify,
         .alarm = pAlarm->alarm_id,
-        .alarm_value_hi = XSyncValueHigh32(pTrigger->test_value),
-        .alarm_value_lo = XSyncValueLow32(pTrigger->test_value),
+        .alarm_value_hi = pTrigger->test_value >> 32,
+        .alarm_value_lo = pTrigger->test_value,
         .time = currentTime.milliseconds,
         .state = pAlarm->state
     };
 
     if (pTrigger->pSync && SYNC_COUNTER == pTrigger->pSync->type) {
-        ane.counter_value_hi = XSyncValueHigh32(pCounter->value);
-        ane.counter_value_lo = XSyncValueLow32(pCounter->value);
+        ane.counter_value_hi = pCounter->value >> 32;
+        ane.counter_value_lo = pCounter->value;
     }
     else {
         /* XXX what else can we do if there's no counter? */
@@ -487,13 +484,13 @@ SyncSendCounterNotifyEvents(ClientPtr client, SyncAwait ** ppAwait,
         pev->type = SyncEventBase + XSyncCounterNotify;
         pev->kind = XSyncCounterNotify;
         pev->counter = pTrigger->pSync->id;
-        pev->wait_value_lo = XSyncValueLow32(pTrigger->test_value);
-        pev->wait_value_hi = XSyncValueHigh32(pTrigger->test_value);
+        pev->wait_value_lo = pTrigger->test_value;
+        pev->wait_value_hi = pTrigger->test_value >> 32;
         if (SYNC_COUNTER == pTrigger->pSync->type) {
             SyncCounter *pCounter = (SyncCounter *) pTrigger->pSync;
 
-            pev->counter_value_lo = XSyncValueLow32(pCounter->value);
-            pev->counter_value_hi = XSyncValueHigh32(pCounter->value);
+            pev->counter_value_lo = pCounter->value;
+            pev->counter_value_hi = pCounter->value >> 32;
         }
         else {
             pev->counter_value_lo = 0;
@@ -530,7 +527,7 @@ SyncAlarmTriggerFired(SyncTrigger * pTrigger)
 {
     SyncAlarm *pAlarm = (SyncAlarm *) pTrigger;
     SyncCounter *pCounter;
-    CARD64 new_test_value;
+    int64_t new_test_value;
 
     if (!SyncCheckWarnIsCounter(pTrigger->pSync, WARN_INVALID_COUNTER_ALARM))
         return;
@@ -546,7 +543,7 @@ SyncAlarmTriggerFired(SyncTrigger * pTrigger)
      *    no change is made to value (test-value) and the alarm
      *    state is changed to Inactive before the event is generated."
      */
-    if (pCounter == NULL || (XSyncValueIsZero(pAlarm->delta)
+    if (pCounter == NULL || (pAlarm->delta == 0
                              && (pAlarm->trigger.test_type ==
                                  XSyncPositiveComparison ||
                                  pAlarm->trigger.test_type ==
@@ -557,7 +554,7 @@ SyncAlarmTriggerFired(SyncTrigger * pTrigger)
 
     if (pAlarm->state == XSyncAlarmActive) {
         Bool overflow;
-        CARD64 oldvalue;
+        int64_t oldvalue;
         SyncTrigger *paTrigger = &pAlarm->trigger;
         SyncCounter *paCounter;
 
@@ -576,8 +573,8 @@ SyncAlarmTriggerFired(SyncTrigger * pTrigger)
         /* XXX really should do something smarter here */
 
         do {
-            XSyncValueAdd(&paTrigger->test_value, paTrigger->test_value,
-                          pAlarm->delta, &overflow);
+            overflow = checked_int64_add(&paTrigger->test_value,
+                                         paTrigger->test_value, pAlarm->delta);
         } while (!overflow &&
                  (*paTrigger->CheckTrigger) (paTrigger, paCounter->value));
 
@@ -636,7 +633,7 @@ SyncAwaitTriggerFired(SyncTrigger * pTrigger)
      *  be stored in the events.
      */
     for (; numwaits; numwaits--, pAwait++) {
-        CARD64 diff;
+        int64_t diff;
         Bool overflow, diffgreater, diffequal;
 
         /* "A CounterNotify event with the destroyed flag set to TRUE is
@@ -655,16 +652,16 @@ SyncAwaitTriggerFired(SyncTrigger * pTrigger)
              *  calculated by subtracting the test value from the value of
              *  the counter."
              */
-            XSyncValueSubtract(&diff, pCounter->value,
-                               pAwait->trigger.test_value, &overflow);
+            overflow = checked_int64_subtract(&diff, pCounter->value,
+                                              pAwait->trigger.test_value);
 
             /* "If the difference lies outside the range for an INT64, an
              *  event is not generated."
              */
             if (overflow)
                 continue;
-            diffgreater = XSyncValueGreaterThan(diff, pAwait->event_threshold);
-            diffequal = XSyncValueEqual(diff, pAwait->event_threshold);
+            diffgreater = diff >= pAwait->event_threshold;
+            diffequal = diff == pAwait->event_threshold;
 
             /* "If the test-type is PositiveTransition or
              *  PositiveComparison, a CounterNotify event is generated if
@@ -699,10 +696,10 @@ SyncAwaitTriggerFired(SyncTrigger * pTrigger)
     FreeResource(pAwaitUnion->header.delete_id, RT_NONE);
 }
 
-static CARD64
-SyncUpdateCounter(SyncCounter *pCounter, CARD64 newval)
+static int64_t
+SyncUpdateCounter(SyncCounter *pCounter, int64_t newval)
 {
-    CARD64 oldval = pCounter->value;
+    int64_t oldval = pCounter->value;
     pCounter->value = newval;
     return oldval;
 }
@@ -711,10 +708,10 @@ SyncUpdateCounter(SyncCounter *pCounter, CARD64 newval)
  *  any triggers depending on the counter will be checked.
  */
 void
-SyncChangeCounter(SyncCounter * pCounter, CARD64 newval)
+SyncChangeCounter(SyncCounter * pCounter, int64_t newval)
 {
     SyncTriggerList *ptl, *pnext;
-    CARD64 oldval;
+    int64_t oldval;
 
     oldval = SyncUpdateCounter(pCounter, newval);
 
@@ -822,7 +819,7 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm * pAlarm, Mask mask,
 
         case XSyncCAValue:
             mask &= ~XSyncCAValue;
-            XSyncIntsToValue(&pAlarm->trigger.wait_value, values[1], values[0]);
+            pAlarm->trigger.wait_value = ((int64_t)values[0] << 32) | values[1];
             values += 2;
             break;
 
@@ -834,7 +831,7 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm * pAlarm, Mask mask,
 
         case XSyncCADelta:
             mask &= ~XSyncCADelta;
-            XSyncIntsToValue(&pAlarm->delta, values[1], values[0]);
+            pAlarm->delta = ((int64_t)values[0] << 32) | values[1];
             values += 2;
             break;
 
@@ -862,16 +859,13 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm * pAlarm, Mask mask,
      *  greater than zero, a Match error is generated."
      */
     if (origmask & (XSyncCADelta | XSyncCATestType)) {
-        CARD64 zero;
-
-        XSyncIntToValue(&zero, 0);
         if ((((pAlarm->trigger.test_type == XSyncPositiveComparison) ||
               (pAlarm->trigger.test_type == XSyncPositiveTransition))
-             && XSyncValueLessThan(pAlarm->delta, zero))
+             && pAlarm->delta < 0)
             ||
             (((pAlarm->trigger.test_type == XSyncNegativeComparison) ||
               (pAlarm->trigger.test_type == XSyncNegativeTransition))
-             && XSyncValueGreaterThan(pAlarm->delta, zero))
+             && pAlarm->delta >= 0)
             ) {
             return BadMatch;
         }
@@ -953,7 +947,7 @@ SyncFDFromFence(ClientPtr client, DrawablePtr pDraw, SyncFence *pFence)
 }
 
 static SyncCounter *
-SyncCreateCounter(ClientPtr client, XSyncCounter id, CARD64 initialvalue)
+SyncCreateCounter(ClientPtr client, XSyncCounter id, int64_t initialvalue)
 {
     SyncCounter *pCounter;
 
@@ -977,8 +971,8 @@ static int FreeCounter(void *, XID);
 
 SyncCounter*
 SyncCreateSystemCounter(const char *name,
-                        CARD64 initial,
-                        CARD64 resolution,
+                        int64_t initial,
+                        int64_t resolution,
                         SyncCounterType counterType,
                         SyncSystemCounterQueryValue QueryValue,
                         SyncSystemCounterBracketValues BracketValues
@@ -1002,8 +996,8 @@ SyncCreateSystemCounter(const char *name,
         psci->QueryValue = QueryValue;
         psci->BracketValues = BracketValues;
         psci->private = NULL;
-        XSyncMaxValue(&psci->bracket_greater);
-        XSyncMinValue(&psci->bracket_less);
+        psci->bracket_greater = LLONG_MAX;
+        psci->bracket_less = LLONG_MIN;
         xorg_list_add(&psci->entry, &SysCounterList);
     }
     return pCounter;
@@ -1023,8 +1017,8 @@ SyncComputeBracketValues(SyncCounter * pCounter)
     SyncTriggerList *pCur;
     SyncTrigger *pTrigger;
     SysCounterInfo *psci;
-    CARD64 *pnewgtval = NULL;
-    CARD64 *pnewltval = NULL;
+    int64_t *pnewgtval = NULL;
+    int64_t *pnewltval = NULL;
     SyncCounterType ct;
 
     if (!pCounter)
@@ -1035,44 +1029,42 @@ SyncComputeBracketValues(SyncCounter * pCounter)
     if (ct == XSyncCounterNeverChanges)
         return;
 
-    XSyncMaxValue(&psci->bracket_greater);
-    XSyncMinValue(&psci->bracket_less);
+    psci->bracket_greater = LLONG_MAX;
+    psci->bracket_less = LLONG_MIN;
 
     for (pCur = pCounter->sync.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)) {
+            if (pCounter->value < pTrigger->test_value &&
+                pTrigger->test_value < psci->bracket_greater) {
                 psci->bracket_greater = pTrigger->test_value;
                 pnewgtval = &psci->bracket_greater;
             }
-            else if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value) &&
-                     XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)) {
+            else if (pCounter->value > pTrigger->test_value &&
+                     pTrigger->test_value > psci->bracket_less) {
                     psci->bracket_less = pTrigger->test_value;
                     pnewltval = &psci->bracket_less;
             }
         }
         else if (pTrigger->test_type == XSyncNegativeComparison &&
                  ct != XSyncCounterNeverDecreases) {
-            if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value) &&
-                XSyncValueGreaterThan(pTrigger->test_value,
-                                      psci->bracket_less)) {
+            if (pCounter->value > pTrigger->test_value &&
+                pTrigger->test_value > psci->bracket_less) {
                 psci->bracket_less = pTrigger->test_value;
                 pnewltval = &psci->bracket_less;
             }
-            else if (XSyncValueLessThan(pCounter->value, pTrigger->test_value) &&
-                     XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)) {
+            else if (pCounter->value < pTrigger->test_value &&
+                     pTrigger->test_value < psci->bracket_greater) {
                     psci->bracket_greater = pTrigger->test_value;
                     pnewgtval = &psci->bracket_greater;
             }
         }
         else if (pTrigger->test_type == XSyncNegativeTransition &&
                  ct != XSyncCounterNeverIncreases) {
-            if (XSyncValueGreaterOrEqual(pCounter->value, pTrigger->test_value) &&
-                XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)) {
+            if (pCounter->value >= pTrigger->test_value &&
+                pTrigger->test_value > psci->bracket_less) {
                     /*
                      * If the value is exactly equal to our threshold, we want one
                      * more event in the negative direction to ensure we pick up
@@ -1081,16 +1073,16 @@ SyncComputeBracketValues(SyncCounter * pCounter)
                     psci->bracket_less = pTrigger->test_value;
                     pnewltval = &psci->bracket_less;
             }
-            else if (XSyncValueLessThan(pCounter->value, pTrigger->test_value) &&
-                     XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)) {
+            else if (pCounter->value < pTrigger->test_value &&
+                     pTrigger->test_value < psci->bracket_greater) {
                     psci->bracket_greater = pTrigger->test_value;
                     pnewgtval = &psci->bracket_greater;
             }
         }
         else if (pTrigger->test_type == XSyncPositiveTransition &&
                  ct != XSyncCounterNeverDecreases) {
-            if (XSyncValueLessOrEqual(pCounter->value, pTrigger->test_value) &&
-                XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)) {
+            if (pCounter->value <= pTrigger->test_value &&
+                pTrigger->test_value < psci->bracket_greater) {
                     /*
                      * If the value is exactly equal to our threshold, we
                      * want one more event in the positive direction to
@@ -1100,8 +1092,8 @@ SyncComputeBracketValues(SyncCounter * pCounter)
                     psci->bracket_greater = pTrigger->test_value;
                     pnewgtval = &psci->bracket_greater;
             }
-            else if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value) &&
-                     XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)) {
+            else if (pCounter->value > pTrigger->test_value &&
+                     pTrigger->test_value > psci->bracket_less) {
                     psci->bracket_less = pTrigger->test_value;
                     pnewltval = &psci->bracket_less;
             }
@@ -1283,8 +1275,8 @@ ProcSyncListSystemCounters(ClientPtr client)
         char *pname_in_reply;
 
         walklist->counter = psci->pCounter->sync.id;
-        walklist->resolution_hi = XSyncValueHigh32(psci->resolution);
-        walklist->resolution_lo = XSyncValueLow32(psci->resolution);
+        walklist->resolution_hi = psci->resolution >> 32;
+        walklist->resolution_lo = psci->resolution;
         namelen = strlen(psci->name);
         walklist->name_length = namelen;
 
@@ -1391,14 +1383,14 @@ static int
 ProcSyncCreateCounter(ClientPtr client)
 {
     REQUEST(xSyncCreateCounterReq);
-    CARD64 initial;
+    int64_t initial;
 
     REQUEST_SIZE_MATCH(xSyncCreateCounterReq);
 
     LEGAL_NEW_RESOURCE(stuff->cid, client);
 
-    XSyncIntsToValue(&initial, stuff->initial_value_lo,
-                     stuff->initial_value_hi);
+    initial = ((int64_t)stuff->initial_value_hi << 32) | stuff->initial_value_lo;
+
     if (!SyncCreateCounter(client, stuff->cid, initial))
         return BadAlloc;
 
@@ -1413,7 +1405,7 @@ ProcSyncSetCounter(ClientPtr client)
 {
     REQUEST(xSyncSetCounterReq);
     SyncCounter *pCounter;
-    CARD64 newvalue;
+    int64_t newvalue;
     int rc;
 
     REQUEST_SIZE_MATCH(xSyncSetCounterReq);
@@ -1428,7 +1420,7 @@ ProcSyncSetCounter(ClientPtr client)
         return BadAccess;
     }
 
-    XSyncIntsToValue(&newvalue, stuff->value_lo, stuff->value_hi);
+    newvalue = ((int64_t)stuff->value_hi << 32) | stuff->value_lo;
     SyncChangeCounter(pCounter, newvalue);
     return Success;
 }
@@ -1441,7 +1433,7 @@ ProcSyncChangeCounter(ClientPtr client)
 {
     REQUEST(xSyncChangeCounterReq);
     SyncCounter *pCounter;
-    CARD64 newvalue;
+    int64_t newvalue;
     Bool overflow;
     int rc;
 
@@ -1457,8 +1449,8 @@ ProcSyncChangeCounter(ClientPtr client)
         return BadAccess;
     }
 
-    XSyncIntsToValue(&newvalue, stuff->value_lo, stuff->value_hi);
-    XSyncValueAdd(&newvalue, pCounter->value, newvalue, &overflow);
+    newvalue = (int64_t)stuff->value_hi << 32 | stuff->value_lo;
+    overflow = checked_int64_add(&newvalue, newvalue, pCounter->value);
     if (overflow) {
         /* XXX 64 bit value can't fit in 32 bits; do the best we can */
         client->errorValue = stuff->value_hi;
@@ -1529,7 +1521,7 @@ SyncAwaitEpilogue(ClientPtr client, int items, SyncAwaitUnion * pAwaitUnion)
 
     pAwait = &(pAwaitUnion + 1)->await; /* skip over header */
     for (i = 0; i < items; i++, pAwait++) {
-        CARD64 value;
+        int64_t value;
 
         /*  don't have to worry about NULL counters because the request
          *  errors before we get here out if they occur
@@ -1539,7 +1531,7 @@ SyncAwaitEpilogue(ClientPtr client, int items, SyncAwaitUnion * pAwaitUnion)
             value = ((SyncCounter *) pAwait->trigger.pSync)->value;
             break;
         default:
-            XSyncIntToValue(&value, 0);
+            value = 0;
         }
 
         if ((*pAwait->trigger.CheckTrigger) (&pAwait->trigger, value)) {
@@ -1598,9 +1590,9 @@ ProcSyncAwait(ClientPtr client)
         /* sanity checks are in SyncInitTrigger */
         pAwait->trigger.pSync = NULL;
         pAwait->trigger.value_type = pProtocolWaitConds->value_type;
-        XSyncIntsToValue(&pAwait->trigger.wait_value,
-                         pProtocolWaitConds->wait_value_lo,
-                         pProtocolWaitConds->wait_value_hi);
+        pAwait->trigger.wait_value =
+            ((int64_t)pProtocolWaitConds->wait_value_hi << 32) |
+            pProtocolWaitConds->wait_value_lo;
         pAwait->trigger.test_type = pProtocolWaitConds->test_type;
 
         status = SyncInitTrigger(client, &pAwait->trigger,
@@ -1616,9 +1608,10 @@ ProcSyncAwait(ClientPtr client)
         /* this is not a mistake -- same function works for both cases */
         pAwait->trigger.TriggerFired = SyncAwaitTriggerFired;
         pAwait->trigger.CounterDestroyed = SyncAwaitTriggerFired;
-        XSyncIntsToValue(&pAwait->event_threshold,
-                         pProtocolWaitConds->event_threshold_lo,
-                         pProtocolWaitConds->event_threshold_hi);
+        pAwait->event_threshold =
+            ((int64_t) pProtocolWaitConds->event_threshold_hi << 32) |
+            pProtocolWaitConds->event_threshold_lo;
+
         pAwait->pHeader = &pAwaitUnion->header;
         pAwaitUnion->header.num_waitconditions++;
     }
@@ -1656,8 +1649,8 @@ ProcSyncQueryCounter(ClientPtr client)
         .type = X_Reply,
         .sequenceNumber = client->sequence,
         .length = 0,
-        .value_hi = XSyncValueHigh32(pCounter->value),
-        .value_lo = XSyncValueLow32(pCounter->value)
+        .value_hi = pCounter->value >> 32,
+        .value_lo = pCounter->value
     };
 
     if (client->swapped) {
@@ -1701,7 +1694,7 @@ ProcSyncCreateAlarm(ClientPtr client)
     pTrigger = &pAlarm->trigger;
     pTrigger->pSync = NULL;
     pTrigger->value_type = XSyncAbsolute;
-    XSyncIntToValue(&pTrigger->wait_value, 0L);
+    pTrigger->wait_value = 0;
     pTrigger->test_type = XSyncPositiveComparison;
     pTrigger->TriggerFired = SyncAlarmTriggerFired;
     pTrigger->CounterDestroyed = SyncAlarmCounterDestroyed;
@@ -1714,7 +1707,7 @@ ProcSyncCreateAlarm(ClientPtr client)
 
     pAlarm->client = client;
     pAlarm->alarm_id = stuff->id;
-    XSyncIntToValue(&pAlarm->delta, 1L);
+    pAlarm->delta = 1;
     pAlarm->events = TRUE;
     pAlarm->state = XSyncAlarmInactive;
     pAlarm->pEventClients = NULL;
@@ -1826,17 +1819,17 @@ ProcSyncQueryAlarm(ClientPtr client)
         * on.
         */
         .value_type = pTrigger->value_type,
-        .wait_value_hi = XSyncValueHigh32(pTrigger->wait_value),
-        .wait_value_lo = XSyncValueLow32(pTrigger->wait_value),
+        .wait_value_hi = pTrigger->wait_value >> 32,
+        .wait_value_lo = pTrigger->wait_value,
 #else
         .value_type = XSyncAbsolute,
-        .wait_value_hi = XSyncValueHigh32(pTrigger->test_value),
-        .wait_value_lo = XSyncValueLow32(pTrigger->test_value),
+        .wait_value_hi = pTrigger->test_value >> 32,
+        .wait_value_lo = pTrigger->test_value,
 #endif
 
         .test_type = pTrigger->test_type,
-        .delta_hi = XSyncValueHigh32(pAlarm->delta),
-        .delta_lo = XSyncValueLow32(pAlarm->delta),
+        .delta_hi = pAlarm->delta >> 32,
+        .delta_lo = pAlarm->delta,
         .events = pAlarm->events,
         .state = pAlarm->state
     };
@@ -2067,7 +2060,7 @@ ProcSyncAwaitFence(ClientPtr client)
          * satisfy SyncInitTrigger's validation logic
          */
         pAwait->trigger.value_type = XSyncAbsolute;
-        XSyncIntToValue(&pAwait->trigger.wait_value, 0);
+        pAwait->trigger.wait_value = 0;
         pAwait->trigger.test_type = 0;
 
         status = SyncInitTrigger(client, &pAwait->trigger,
@@ -2083,7 +2076,7 @@ ProcSyncAwaitFence(ClientPtr client)
         pAwait->trigger.TriggerFired = SyncAwaitTriggerFired;
         pAwait->trigger.CounterDestroyed = SyncAwaitTriggerFired;
         /* event_threshold is unused for fence syncs */
-        XSyncIntToValue(&pAwait->event_threshold, 0);
+        pAwait->event_threshold = 0;
         pAwait->pHeader = &pAwaitUnion->header;
         pAwaitUnion->header.num_waitconditions++;
     }
@@ -2541,15 +2534,18 @@ SyncExtensionInit(void)
  */
 
 static void *ServertimeCounter;
-static XSyncValue Now;
-static XSyncValue *pnext_time;
+static int64_t Now;
+static int64_t *pnext_time;
 
-#define GetTime()\
-{\
-    unsigned long millis = GetTimeInMillis();\
-    unsigned long maxis = XSyncValueHigh32(Now);\
-    if (millis < XSyncValueLow32(Now)) maxis++;\
-    XSyncIntsToValue(&Now, millis, maxis);\
+static void GetTime(void)
+{
+    unsigned long millis = GetTimeInMillis();
+    unsigned long maxis = Now >> 32;
+
+    if (millis < (Now & 0xffffffff))
+        maxis++;
+
+    Now = ((int64_t)maxis << 32) | millis;
 }
 
 /*
@@ -2559,21 +2555,16 @@ static XSyncValue *pnext_time;
 /*ARGSUSED*/ static void
 ServertimeBlockHandler(void *env, void *wt)
 {
-    XSyncValue delay;
     unsigned long timeout;
 
     if (pnext_time) {
         GetTime();
 
-        if (XSyncValueGreaterOrEqual(Now, *pnext_time)) {
+        if (Now >= *pnext_time) {
             timeout = 0;
         }
         else {
-            Bool overflow;
-
-            XSyncValueSubtract(&delay, *pnext_time, Now, &overflow);
-            (void) overflow;
-            timeout = XSyncValueLow32(delay);
+            timeout = *pnext_time - Now;
         }
         AdjustWaitForDelay(wt, timeout);        /* os/utils.c */
     }
@@ -2588,22 +2579,22 @@ ServertimeWakeupHandler(void *env, int rc)
     if (pnext_time) {
         GetTime();
 
-        if (XSyncValueGreaterOrEqual(Now, *pnext_time)) {
+        if (Now >= *pnext_time) {
             SyncChangeCounter(ServertimeCounter, Now);
         }
     }
 }
 
 static void
-ServertimeQueryValue(void *pCounter, CARD64 * pValue_return)
+ServertimeQueryValue(void *pCounter, int64_t *pValue_return)
 {
     GetTime();
     *pValue_return = Now;
 }
 
 static void
-ServertimeBracketValues(void *pCounter, CARD64 * pbracket_less,
-                        CARD64 * pbracket_greater)
+ServertimeBracketValues(void *pCounter, int64_t *pbracket_less,
+                        int64_t *pbracket_greater)
 {
     if (!pnext_time && pbracket_greater) {
         RegisterBlockAndWakeupHandlers(ServertimeBlockHandler,
@@ -2619,10 +2610,9 @@ ServertimeBracketValues(void *pCounter, CARD64 * pbracket_less,
 static void
 SyncInitServerTime(void)
 {
-    CARD64 resolution;
+    int64_t resolution = 4;
 
-    XSyncIntsToValue(&Now, GetTimeInMillis(), 0);
-    XSyncIntToValue(&resolution, 4);
+    Now = GetTimeInMillis();
     ServertimeCounter = SyncCreateSystemCounter("SERVERTIME", Now, resolution,
                                                 XSyncCounterNeverDecreases,
                                                 ServertimeQueryValue,
@@ -2635,13 +2625,13 @@ SyncInitServerTime(void)
  */
 
 typedef struct {
-    XSyncValue *value_less;
-    XSyncValue *value_greater;
+    int64_t *value_less;
+    int64_t *value_greater;
     int deviceid;
 } IdleCounterPriv;
 
 static void
-IdleTimeQueryValue(void *pCounter, CARD64 * pValue_return)
+IdleTimeQueryValue(void *pCounter, int64_t *pValue_return)
 {
     int deviceid;
     CARD32 idle;
@@ -2654,7 +2644,7 @@ IdleTimeQueryValue(void *pCounter, CARD64 * pValue_return)
     else
         deviceid = XIAllDevices;
     idle = GetTimeInMillis() - LastEventTime(deviceid).milliseconds;
-    XSyncIntsToValue(pValue_return, idle, 0);
+    *pValue_return = idle;
 }
 
 static void
@@ -2662,9 +2652,9 @@ IdleTimeBlockHandler(void *pCounter, void *wt)
 {
     SyncCounter *counter = pCounter;
     IdleCounterPriv *priv = SysCounterGetPrivate(counter);
-    XSyncValue *less = priv->value_less,
-               *greater = priv->value_greater;
-    XSyncValue idle, old_idle;
+    int64_t *less = priv->value_less;
+    int64_t *greater = priv->value_greater;
+    int64_t idle, old_idle;
     SyncTriggerList *list = counter->sync.pTriglist;
     SyncTrigger *trig;
 
@@ -2681,10 +2671,10 @@ IdleTimeBlockHandler(void *pCounter, void *wt)
      * may be past the lower bracket if we dawdled with the events, so
      * check for whether we did reset and bomb out of select immediately.
      */
-    if (less && XSyncValueGreaterThan(idle, *less) &&
+    if (less && idle > *less &&
         LastEventTimeWasReset(priv->deviceid)) {
         AdjustWaitForDelay(wt, 0);
-    } else if (less && XSyncValueLessOrEqual(idle, *less)) {
+    } else if (less && idle <= *less) {
         /*
          * 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
@@ -2706,7 +2696,7 @@ IdleTimeBlockHandler(void *pCounter, void *wt)
          * idle time greater than this.  Schedule a wakeup for the next
          * millisecond so we won't miss a transition.
          */
-        if (XSyncValueEqual(idle, *less))
+        if (idle == *less)
             AdjustWaitForDelay(wt, 1);
     }
     else if (greater) {
@@ -2717,12 +2707,8 @@ IdleTimeBlockHandler(void *pCounter, void *wt)
          * that level-triggered, schedule an immediate wakeup.
          */
 
-        if (XSyncValueLessThan(idle, *greater)) {
-            XSyncValue value;
-            Bool overflow;
-
-            XSyncValueSubtract(&value, *greater, idle, &overflow);
-            AdjustWaitForDelay(wt, XSyncValueLow32(value));
+        if (idle < *greater) {
+            AdjustWaitForDelay(wt, *greater - idle);
         }
         else {
             for (list = counter->sync.pTriglist; list;
@@ -2740,10 +2726,11 @@ IdleTimeBlockHandler(void *pCounter, void *wt)
 }
 
 static void
-IdleTimeCheckBrackets(SyncCounter *counter, XSyncValue idle, XSyncValue *less, XSyncValue *greater)
+IdleTimeCheckBrackets(SyncCounter *counter, int64_t idle,
+                      int64_t *less, int64_t *greater)
 {
-    if ((greater && XSyncValueGreaterOrEqual(idle, *greater)) ||
-        (less && XSyncValueLessOrEqual(idle, *less))) {
+    if ((greater && idle >= *greater) ||
+        (less && idle <= *less)) {
         SyncChangeCounter(counter, idle);
     }
     else
@@ -2755,9 +2742,9 @@ IdleTimeWakeupHandler(void *pCounter, int rc)
 {
     SyncCounter *counter = pCounter;
     IdleCounterPriv *priv = SysCounterGetPrivate(counter);
-    XSyncValue *less = priv->value_less,
-               *greater = priv->value_greater;
-    XSyncValue idle;
+    int64_t *less = priv->value_less;
+    int64_t *greater = priv->value_greater;
+    int64_t idle;
 
     if (!less && !greater)
         return;
@@ -2772,10 +2759,8 @@ IdleTimeWakeupHandler(void *pCounter, int rc)
       */
     if (LastEventTimeWasReset(priv->deviceid)) {
         LastEventTimeToggleResetFlag(priv->deviceid, FALSE);
-        if (!XSyncValueIsZero(idle)) {
-            XSyncValue zero;
-            XSyncIntsToValue(&zero, 0, 0);
-            IdleTimeCheckBrackets(counter, zero, less, greater);
+        if (idle != 0) {
+            IdleTimeCheckBrackets(counter, 0, less, greater);
             less = priv->value_less;
             greater = priv->value_greater;
         }
@@ -2785,13 +2770,13 @@ IdleTimeWakeupHandler(void *pCounter, int rc)
 }
 
 static void
-IdleTimeBracketValues(void *pCounter, CARD64 * pbracket_less,
-                      CARD64 * pbracket_greater)
+IdleTimeBracketValues(void *pCounter, int64_t *pbracket_less,
+                      int64_t *pbracket_greater)
 {
     SyncCounter *counter = pCounter;
     IdleCounterPriv *priv = SysCounterGetPrivate(counter);
-    XSyncValue *less = priv->value_less,
-               *greater = priv->value_greater;
+    int64_t *less = priv->value_less;
+    int64_t *greater = priv->value_greater;
     Bool registered = (less || greater);
 
     if (registered && !pbracket_less && !pbracket_greater) {
@@ -2813,12 +2798,11 @@ IdleTimeBracketValues(void *pCounter, CARD64 * pbracket_less,
 static SyncCounter*
 init_system_idle_counter(const char *name, int deviceid)
 {
-    CARD64 resolution;
-    XSyncValue idle;
+    int64_t resolution = 4;
+    int64_t idle;
     SyncCounter *idle_time_counter;
 
     IdleTimeQueryValue(NULL, &idle);
-    XSyncIntToValue(&resolution, 4);
 
     idle_time_counter = SyncCreateSystemCounter(name, idle, resolution,
                                                 XSyncCounterUnrestricted,
diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h
index a8062d1c6..63f91a980 100644
--- a/Xext/syncsrv.h
+++ b/Xext/syncsrv.h
@@ -67,19 +67,19 @@ typedef enum {
 } SyncCounterType;
 
 typedef void (*SyncSystemCounterQueryValue)(void *counter,
-                                            CARD64 *value_return
+                                            int64_t *value_return
     );
 typedef void (*SyncSystemCounterBracketValues)(void *counter,
-                                               CARD64 *pbracket_less,
-                                               CARD64 *pbracket_greater
+                                               int64_t *pbracket_less,
+                                               int64_t *pbracket_greater
     );
 
 typedef struct _SysCounterInfo {
     SyncCounter *pCounter;
     char *name;
-    CARD64 resolution;
-    CARD64 bracket_greater;
-    CARD64 bracket_less;
+    int64_t resolution;
+    int64_t bracket_greater;
+    int64_t bracket_less;
     SyncCounterType counterType;        /* how can this counter change */
     SyncSystemCounterQueryValue QueryValue;
     SyncSystemCounterBracketValues BracketValues;
@@ -97,7 +97,7 @@ typedef struct _SyncAlarm {
     SyncTrigger trigger;
     ClientPtr client;
     XSyncAlarm alarm_id;
-    CARD64 delta;
+    int64_t delta;
     int events;
     int state;
     SyncAlarmClientList *pEventClients;
@@ -111,7 +111,7 @@ typedef struct {
 
 typedef struct {
     SyncTrigger trigger;
-    CARD64 event_threshold;
+    int64_t event_threshold;
     SyncAwaitHeader *pHeader;
 } SyncAwait;
 
@@ -121,16 +121,15 @@ typedef union {
 } SyncAwaitUnion;
 
 extern SyncCounter* SyncCreateSystemCounter(const char *name,
-                                            CARD64 initial_value,
-                                            CARD64 resolution,
+                                            int64_t initial_value,
+                                            int64_t resolution,
                                             SyncCounterType counterType,
                                             SyncSystemCounterQueryValue QueryValue,
                                             SyncSystemCounterBracketValues BracketValues
     );
 
 extern void SyncChangeCounter(SyncCounter *pCounter,
-                              CARD64 new_value
-    );
+                              int64_t new_value);
 
 extern void SyncDestroySystemCounter(void *pCounter);
 
diff --git a/include/misc.h b/include/misc.h
index 38af70ff9..9d0e422e3 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -324,6 +324,35 @@ bswap_32(uint32_t x)
             ((x & 0x000000FF) << 24));
 }
 
+static inline Bool
+checked_int64_add(int64_t *out, int64_t a, int64_t b)
+{
+    /* Do the potentially overflowing math as uint64_t, as signed
+     * integers in C are undefined on overflow (and the compiler may
+     * optimize out our overflow check below, otherwise)
+     */
+    int64_t result = (uint64_t)a + (uint64_t)b;
+    /* signed addition overflows if operands have the same sign, and
+     * the sign of the result doesn't match the sign of the inputs.
+     */
+    Bool overflow = (a < 0) == (b < 0) && (a < 0) != (result < 0);
+
+    *out = result;
+
+    return overflow;
+}
+
+static inline Bool
+checked_int64_subtract(int64_t *out, int64_t a, int64_t b)
+{
+    int64_t result = (uint64_t)a - (uint64_t)b;
+    Bool overflow = (a < 0) != (b < 0) && (a < 0) != (result < 0);
+
+    *out = result;
+
+    return overflow;
+}
+
 #define swapl(x) do { \
 		if (sizeof(*(x)) != 4) \
 			wrong_size(); \
diff --git a/miext/sync/misync.c b/miext/sync/misync.c
index 3d03d1b59..490fa0b17 100644
--- a/miext/sync/misync.c
+++ b/miext/sync/misync.c
@@ -127,16 +127,13 @@ void
 miSyncTriggerFence(SyncFence * pFence)
 {
     SyncTriggerList *ptl, *pNext;
-    CARD64 unused;
 
     pFence->funcs.SetTriggered(pFence);
 
-    XSyncIntToValue(&unused, 0L);
-
     /* run through triggers to see if any fired */
     for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext) {
         pNext = ptl->next;
-        if ((*ptl->pTrigger->CheckTrigger) (ptl->pTrigger, unused))
+        if ((*ptl->pTrigger->CheckTrigger) (ptl->pTrigger, 0))
             (*ptl->pTrigger->TriggerFired) (ptl->pTrigger);
     }
 }
diff --git a/miext/sync/misyncstr.h b/miext/sync/misyncstr.h
index ad69e8eca..084ca4c82 100644
--- a/miext/sync/misyncstr.h
+++ b/miext/sync/misyncstr.h
@@ -28,13 +28,12 @@
 #ifndef _MISYNCSTR_H_
 #define _MISYNCSTR_H_
 
+#include <stdint.h>
 #include "dix.h"
 #include "misync.h"
 #include "scrnintstr.h"
 #include <X11/extensions/syncconst.h>
 
-#define CARD64 XSyncValue       /* XXX temporary! need real 64 bit values for Alpha */
-
 /* Sync object types */
 #define SYNC_COUNTER		0
 #define SYNC_FENCE		1
@@ -49,7 +48,7 @@ typedef struct _SyncObject {
 
 typedef struct _SyncCounter {
     SyncObject sync;            /* Common sync object data */
-    CARD64 value;               /* counter value */
+    int64_t value;              /* counter value */
     struct _SysCounterInfo *pSysCounterInfo;    /* NULL if not a system counter */
 } SyncCounter;
 
@@ -63,12 +62,12 @@ struct _SyncFence {
 
 struct _SyncTrigger {
     SyncObject *pSync;
-    CARD64 wait_value;          /* wait value */
+    int64_t wait_value;         /* wait value */
     unsigned int value_type;    /* Absolute or Relative */
     unsigned int test_type;     /* transition or Comparision type */
-    CARD64 test_value;          /* trigger event threshold value */
+    int64_t test_value;         /* trigger event threshold value */
     Bool (*CheckTrigger) (struct _SyncTrigger * /*pTrigger */ ,
-                          CARD64        /*newval */
+                          int64_t        /*newval */
         );
     void (*TriggerFired) (struct _SyncTrigger * /*pTrigger */
         );
diff --git a/present/present_fence.c b/present/present_fence.c
index e09657d31..87e7e17d8 100644
--- a/present/present_fence.c
+++ b/present/present_fence.c
@@ -45,7 +45,7 @@ struct present_fence {
  * SyncTrigger callbacks
  */
 static Bool
-present_fence_sync_check_trigger(SyncTrigger *trigger, XSyncValue oldval)
+present_fence_sync_check_trigger(SyncTrigger *trigger, int64_t oldval)
 {
     struct present_fence        *present_fence = container_of(trigger, struct present_fence, trigger);
 
commit 5cbfa276541e6a621cf9c4b44b75323e90a5bd4c
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Sep 18 17:34:31 2017 -0700

    test: Add basic SYNC tests.
    
    I couldn't find any, and I was modifying the implementation, so I had
    to write some.  I would like the test to end with a "make sure there
    weren't any stray unchecked errors", but I didn't figure out how to do
    that.
    
    v2: Extend sync tests to cover alarm delta and waitvalue changes.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/vfb/meson.build b/hw/vfb/meson.build
index 6566b4590..89acdfacd 100644
--- a/hw/vfb/meson.build
+++ b/hw/vfb/meson.build
@@ -4,7 +4,7 @@ srcs = [
     '../../mi/miinitext.c',
 ]
 
-executable(
+xvfb_server = executable(
     'Xvfb',
     srcs,
     include_directories: inc,
diff --git a/test/meson.build b/test/meson.build
index b71d7e249..3e482d6f1 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -22,3 +22,5 @@ if get_option('xvfb')
         )
     endif
 endif
+
+subdir('sync')
diff --git a/test/sync/meson.build b/test/sync/meson.build
new file mode 100644
index 000000000..dfae75b1e
--- /dev/null
+++ b/test/sync/meson.build
@@ -0,0 +1,9 @@
+xcb_dep = dependency('xcb', required: false)
+xcb_sync_dep = dependency('xcb-sync', required: false)
+
+if get_option('xvfb')
+    if xcb_dep.found() and xcb_sync_dep.found()
+        sync = executable('sync', 'sync.c', dependencies: [xcb_dep, xcb_sync_dep])
+        test('sync', simple_xinit, args: [sync, '--', xvfb_server])
+    endif
+endif
diff --git a/test/sync/sync.c b/test/sync/sync.c
new file mode 100644
index 000000000..f25d3fa37
--- /dev/null
+++ b/test/sync/sync.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright © 2017 Broadcom
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <xcb/sync.h>
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+static const int64_t some_values[] = {
+        0,
+        1,
+        -1,
+        LLONG_MAX,
+        LLONG_MIN,
+};
+
+static int64_t
+pack_sync_value(xcb_sync_int64_t val)
+{
+    return ((int64_t)val.hi << 32) | val.lo;
+}
+
+static int64_t
+counter_value(struct xcb_connection_t *c,
+              xcb_sync_query_counter_cookie_t cookie)
+{
+    xcb_sync_query_counter_reply_t *reply =
+        xcb_sync_query_counter_reply(c, cookie, NULL);
+    int64_t value = pack_sync_value(reply->counter_value);
+
+    free(reply);
+    return value;
+}
+
+static xcb_sync_int64_t
+sync_value(int64_t value)
+{
+    xcb_sync_int64_t v = {
+        .hi = value >> 32,
+        .lo = value,
+    };
+
+    return v;
+}
+
+/* Initializes counters with a bunch of interesting values and makes
+ * sure it comes back the same.
+ */
+static void
+test_create_counter(xcb_connection_t *c)
+{
+    xcb_sync_query_counter_cookie_t queries[ARRAY_SIZE(some_values)];
+
+    for (int i = 0; i < ARRAY_SIZE(some_values); i++) {
+        xcb_sync_counter_t counter = xcb_generate_id(c);
+        xcb_sync_create_counter(c, counter, sync_value(some_values[i]));
+        queries[i] = xcb_sync_query_counter_unchecked(c, counter);
+    }
+
+    for (int i = 0; i < ARRAY_SIZE(some_values); i++) {
+        int64_t value = counter_value(c, queries[i]);
+
+        if (value != some_values[i]) {
+            fprintf(stderr, "Creating counter with %lld returned %lld\n",
+                    (long long)some_values[i],
+                    (long long)value);
+            exit(1);
+        }
+    }
+}
+
+/* Set a single counter to a bunch of interesting values and make sure
+ * it comes the same.
+ */
+static void
+test_set_counter(xcb_connection_t *c)
+{
+    xcb_sync_counter_t counter = xcb_generate_id(c);
+    xcb_sync_query_counter_cookie_t queries[ARRAY_SIZE(some_values)];
+
+    xcb_sync_create_counter(c, counter, sync_value(0));
+
+    for (int i = 0; i < ARRAY_SIZE(some_values); i++) {
+        xcb_sync_set_counter(c, counter, sync_value(some_values[i]));
+        queries[i] = xcb_sync_query_counter_unchecked(c, counter);
+    }
+
+    for (int i = 0; i < ARRAY_SIZE(some_values); i++) {
+        int64_t value = counter_value(c, queries[i]);
+
+        if (value != some_values[i]) {
+            fprintf(stderr, "Setting counter to %lld returned %lld\n",
+                    (long long)some_values[i],
+                    (long long)value);
+            exit(1);
+        }
+    }
+}
+
+/* Add [0, 1, 2, 3] to a counter and check that the values stick. */
+static void
+test_change_counter_basic(xcb_connection_t *c)
+{
+    int iterations = 4;
+    xcb_sync_query_counter_cookie_t queries[iterations];
+
+    xcb_sync_counter_t counter = xcb_generate_id(c);
+    xcb_sync_create_counter(c, counter, sync_value(0));
+
+    for (int i = 0; i < iterations; i++) {
+        xcb_sync_change_counter(c, counter, sync_value(i));
+        queries[i] = xcb_sync_query_counter_unchecked(c, counter);
+    }
+
+    int64_t expected_value = 0;
+    for (int i = 0; i < iterations; i++) {
+        expected_value += i;
+        int64_t value = counter_value(c, queries[i]);
+
+        if (value != expected_value) {
+            fprintf(stderr, "Adding %d to counter expected %lld returned %lld\n",
+                    i,
+                    (long long)expected_value,
+                    (long long)value);
+            exit(1);
+        }
+    }
+}
+
+/* Test change_counter where we trigger an integer overflow. */
+static void
+test_change_counter_overflow(xcb_connection_t *c)
+{
+    int iterations = 4;
+    xcb_sync_query_counter_cookie_t queries[iterations];
+    xcb_void_cookie_t changes[iterations];
+    static const struct {
+        int64_t a, b;
+    } overflow_args[] = {
+        { LLONG_MAX, 1 },
+        { LLONG_MAX, LLONG_MAX },
+        { LLONG_MIN, -1 },
+        { LLONG_MIN, LLONG_MIN },
+    };
+
+    xcb_sync_counter_t counter = xcb_generate_id(c);
+    xcb_sync_create_counter(c, counter, sync_value(0));
+
+    for (int i = 0; i < ARRAY_SIZE(overflow_args); i++) {
+        int64_t a = overflow_args[i].a;
+        int64_t b = overflow_args[i].b;
+        xcb_sync_set_counter(c, counter, sync_value(a));
+        changes[i] = xcb_sync_change_counter_checked(c, counter,
+                                                     sync_value(b));
+        queries[i] = xcb_sync_query_counter(c, counter);
+    }
+
+    for (int i = 0; i < ARRAY_SIZE(overflow_args); i++) {
+        int64_t a = overflow_args[i].a;
+        int64_t b = overflow_args[i].b;
+        xcb_sync_query_counter_reply_t *reply =
+            xcb_sync_query_counter_reply(c, queries[i], NULL);
+        int64_t value = (((int64_t)reply->counter_value.hi << 32) |
+                         reply->counter_value.lo);
+        int64_t expected_value = a;
+
+        /* The change_counter should have thrown BadValue */
+        xcb_generic_error_t *e = xcb_request_check(c, changes[i]);
+        if (!e) {
+            fprintf(stderr, "(%lld + %lld) failed to return an error\n",
+                    (long long)a,
+                    (long long)b);
+            exit(1);
+        }
+
+        if (e->error_code != XCB_VALUE) {
+            fprintf(stderr, "(%lld + %lld) returned %d, not BadValue\n",
+                    (long long)a,
+                    (long long)b,
+                    e->error_code);
+            exit(1);
+        }
+
+        /* The change_counter should have had no other effect if it
+         * errored out.
+         */
+        if (value != expected_value) {
+            fprintf(stderr, "(%lld + %lld) expected %lld returned %lld\n",
+                    (long long)a,
+                    (long long)b,
+                    (long long)expected_value,
+                    (long long)value);
+            exit(1);
+        }
+
+        free(e);
+        free(reply);
+    }
+}
+
+static void
+test_change_alarm_value(xcb_connection_t *c)
+{
+    xcb_sync_alarm_t alarm = xcb_generate_id(c);
+    xcb_sync_query_alarm_cookie_t queries[ARRAY_SIZE(some_values)];
+
+    xcb_sync_create_alarm(c, alarm, 0, NULL);
+
+    for (int i = 0; i < ARRAY_SIZE(some_values); i++) {
+        uint32_t values[] = { some_values[i] >> 32, some_values[i] };
+
+        xcb_sync_change_alarm(c, alarm, XCB_SYNC_CA_VALUE, values);
+        queries[i] = xcb_sync_query_alarm_unchecked(c, alarm);
+    }
+
+    for (int i = 0; i < ARRAY_SIZE(some_values); i++) {
+        xcb_sync_query_alarm_reply_t *reply =
+            xcb_sync_query_alarm_reply(c, queries[i], NULL);
+        int64_t value = pack_sync_value(reply->trigger.wait_value);
+
+        if (value != some_values[i]) {
+            fprintf(stderr, "Setting alarm value to %lld returned %lld\n",
+                    (long long)some_values[i],
+                    (long long)value);
+            exit(1);
+        }
+        free(reply);
+    }
+}
+
+static void
+test_change_alarm_delta(xcb_connection_t *c)
+{
+    xcb_sync_alarm_t alarm = xcb_generate_id(c);
+    xcb_sync_query_alarm_cookie_t queries[ARRAY_SIZE(some_values)];
+
+    xcb_sync_create_alarm(c, alarm, 0, NULL);
+
+    for (int i = 0; i < ARRAY_SIZE(some_values); i++) {
+        uint32_t values[] = { some_values[i] >> 32, some_values[i] };
+
+        xcb_sync_change_alarm(c, alarm, XCB_SYNC_CA_DELTA, values);
+        queries[i] = xcb_sync_query_alarm_unchecked(c, alarm);
+    }
+
+    for (int i = 0; i < ARRAY_SIZE(some_values); i++) {
+        xcb_sync_query_alarm_reply_t *reply =
+            xcb_sync_query_alarm_reply(c, queries[i], NULL);
+        int64_t value = pack_sync_value(reply->delta);
+
+        if (value != some_values[i]) {
+            fprintf(stderr, "Setting alarm delta to %lld returned %lld\n",
+                    (long long)some_values[i],
+                    (long long)value);
+            exit(1);
+        }
+        free(reply);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    int screen;
+    xcb_connection_t *c = xcb_connect(NULL, &screen);
+    xcb_query_extension_reply_t *ext = xcb_get_extension_data(c, &xcb_sync_id);
+
+    if (!ext->present) {
+        printf("No XSync present\n");
+        exit(77);
+    }
+
+    test_create_counter(c);
+    test_set_counter(c);
+    test_change_counter_basic(c);
+    test_change_counter_overflow(c);
+    test_change_alarm_value(c);
+    test_change_alarm_delta(c);
+
+    xcb_disconnect(c);
+    exit(0);
+}
commit 3336291fc68444ee65b48ba675ec947e505fed57
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Sep 18 17:34:30 2017 -0700

    test: Return error from simple-xinit if the client crashes.
    
    I want to be able to call client tests with simple-xinit, so assertion
    failures should be an error.
    
    v2: Clean up identical returns.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>

diff --git a/test/simple-xinit.c b/test/simple-xinit.c
index 89189a609..1fc31be26 100644
--- a/test/simple-xinit.c
+++ b/test/simple-xinit.c
@@ -133,6 +133,9 @@ start_client(char *const *client_args, int display)
             return 1;
         }
 
+        if (!WIFEXITED(wstatus))
+            return 1;
+
         return WEXITSTATUS(wstatus);
     } else {
         execvp(client_args[0], client_args);
commit a8eeb332ccf4d13b3fdcc382397bd3ea45e76212
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Sep 18 17:34:29 2017 -0700

    meson: Add Xvfb and Xephyr-glamor testing.
    
    The Xvfb tests are passing and Xephyr-glamor is failing for me, but it
    fails identically on autotools.  It's disabled on Travis for now
    because the >10 minutes of silence during testing times out the entire
    build.
    
    v2: Fix the disable on travis.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/meson.build b/meson.build
index 3efec0def..ea2a01520 100644
--- a/meson.build
+++ b/meson.build
@@ -426,3 +426,4 @@ libxserver = [
 libxserver += libxserver_dri3
 
 subdir('hw')
+subdir('test')
diff --git a/test/meson.build b/test/meson.build
new file mode 100644
index 000000000..b71d7e249
--- /dev/null
+++ b/test/meson.build
@@ -0,0 +1,24 @@
+simple_xinit = executable(
+    'simple-xinit',
+    'simple-xinit.c',
+    include_directories: inc,
+)
+
+piglit_env = environment()
+piglit_env.set('XSERVER_DIR', meson.source_root())
+piglit_env.set('XSERVER_BUILDDIR', meson.build_root())
+
+if get_option('xvfb')
+    test('xvfb-piglit', find_program('scripts/xvfb-piglit.sh'),
+        env: piglit_env,
+        timeout: 1200,
+    )
+
+    if get_option('xephyr') and build_glamor
+        test('xephyr-glamor',
+            find_program('scripts/xephyr-glamor-piglit.sh'),
+            env: piglit_env,
+            timeout: 1200,
+        )
+    endif
+endif
diff --git a/test/scripts/xephyr-glamor-piglit.sh b/test/scripts/xephyr-glamor-piglit.sh
index 51d42c313..c16fdc4f3 100755
--- a/test/scripts/xephyr-glamor-piglit.sh
+++ b/test/scripts/xephyr-glamor-piglit.sh
@@ -1,3 +1,10 @@
+#!/bin/sh
+
+# this times out on Travis, because the tests take too long.
+if test "x$TRAVIS_BUILD_DIR" != "x"; then
+    exit 77
+fi
+
 # Start a Xephyr server using glamor.  Since the test environment is
 # headless, we start an Xvfb first to host the Xephyr.
 export PIGLIT_RESULTS_DIR=$XSERVER_BUILDDIR/test/piglit-results/xephyr-glamor
diff --git a/test/scripts/xvfb-piglit.sh b/test/scripts/xvfb-piglit.sh
index 763599ef4..ae9f4662e 100755
--- a/test/scripts/xvfb-piglit.sh
+++ b/test/scripts/xvfb-piglit.sh
@@ -1,3 +1,10 @@
+#!/bin/sh
+
+# this times out on Travis, because the tests take too long.
+if test "x$TRAVIS_BUILD_DIR" != "x"; then
+    exit 77
+fi
+
 export SERVER_COMMAND="$XSERVER_BUILDDIR/hw/vfb/Xvfb \
         -noreset \
         -screen scrn 1280x1024x24"
commit a09743c9300f805d6527368ddcf44f5dccd4b366
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Sep 18 17:34:28 2017 -0700

    meson: Move Xvfb build under an option.
    
    Autotools also had it as an option.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/meson.build b/hw/meson.build
index c0d2db3f5..96c1559c3 100644
--- a/hw/meson.build
+++ b/hw/meson.build
@@ -6,7 +6,9 @@ if get_option('dmx')
     subdir('dmx')
 endif
 
-subdir('vfb')
+if get_option('xvfb')
+    subdir('vfb')
+endif
 
 if build_xnest
     subdir('xnest')
diff --git a/meson_options.txt b/meson_options.txt
index fc66f9f08..b1ee6ccc5 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -10,6 +10,8 @@ option('xnest', type: 'combo', choices: ['yes', 'no', 'auto'], value: 'auto',
        description: 'Enable Xnest nested X server')
 option('dmx', type: 'boolean', value: false,
        description: 'Enable DMX nested X server')
+option('xvfb', type: 'boolean', value: true,
+       description: 'Enable Xvfb X server')
 option('xwin', type: 'combo', choices: ['yes', 'no', 'auto'], value: 'auto',
        description: 'Enable XWin X server')
 


More information about the xorg-commit mailing list