Bug Summary

File:Xext/sync.c
Location:line 2668, column 22
Description:Value stored to 'list' during its initialization is never read

Annotated Source Code

1/*
2
3Copyright 1991, 1993, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included
12in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall
23not be used in advertising or otherwise to promote the sale, use or
24other dealings in this Software without prior written authorization
25from The Open Group.
26
27Copyright 1991, 1993 by Digital Equipment Corporation, Maynard, Massachusetts,
28and Olivetti Research Limited, Cambridge, England.
29
30 All Rights Reserved
31
32Permission to use, copy, modify, and distribute this software and its
33documentation for any purpose and without fee is hereby granted,
34provided that the above copyright notice appear in all copies and that
35both that copyright notice and this permission notice appear in
36supporting documentation, and that the names of Digital or Olivetti
37not be used in advertising or publicity pertaining to distribution of the
38software without specific, written prior permission. Digital and Olivetti
39make no representations about the suitability of this software
40for any purpose. It is provided "as is" without express or implied warranty.
41
42DIGITAL AND OLIVETTI DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
43SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
44FITNESS, IN NO EVENT SHALL THEY BE LIABLE FOR ANY SPECIAL, INDIRECT OR
45CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
46USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
47OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
48PERFORMANCE OF THIS SOFTWARE.
49
50*/
51
52#ifdef HAVE_DIX_CONFIG_H1
53#include <dix-config.h>
54#endif
55
56#include <string.h>
57
58#include <X11/X.h>
59#include <X11/Xproto.h>
60#include <X11/Xmd.h>
61#include "scrnintstr.h"
62#include "os.h"
63#include "extnsionst.h"
64#include "dixstruct.h"
65#include "pixmapstr.h"
66#include "resource.h"
67#include "opaque.h"
68#include <X11/extensions/syncproto.h>
69#include "syncsrv.h"
70#include "syncsdk.h"
71#include "protocol-versions.h"
72#include "inputstr.h"
73
74#include <stdio.h>
75#if !defined(WIN32)
76#include <sys/time.h>
77#endif
78
79#include "extinit.h"
80
81/*
82 * Local Global Variables
83 */
84static int SyncEventBase;
85static int SyncErrorBase;
86static RESTYPE RTCounter = 0;
87static RESTYPE RTAwait;
88static RESTYPE RTAlarm;
89static RESTYPE RTAlarmClient;
90static RESTYPE RTFence;
91static struct xorg_list SysCounterList;
92static int SyncNumInvalidCounterWarnings = 0;
93
94#define MAX_INVALID_COUNTER_WARNINGS5 5
95
96static const char *WARN_INVALID_COUNTER_COMPARE =
97 "Warning: Non-counter XSync object using Counter-only\n"
98 " comparison. Result will never be true.\n";
99
100static const char *WARN_INVALID_COUNTER_ALARM =
101 "Warning: Non-counter XSync object used in alarm. This is\n"
102 " the result of a programming error in the X server.\n";
103
104#define IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0))
)
\
105 (pCounter && (pCounter->sync.client == NULL((void*)0)))
106
107/* these are all the alarm attributes that pertain to the alarm's trigger */
108#define XSyncCAAllTrigger((1L<<0) | (1L<<1) | (1L<<2) | (1L<<3
))
\
109 (XSyncCACounter(1L<<0) | XSyncCAValueType(1L<<1) | XSyncCAValue(1L<<2) | XSyncCATestType(1L<<3))
110
111static void SyncComputeBracketValues(SyncCounter *);
112
113static void SyncInitServerTime(void);
114
115static void SyncInitIdleTime(void);
116
117static inline void*
118SysCounterGetPrivate(SyncCounter *counter)
119{
120 BUG_WARN(!IsSystemCounter(counter))do { if (!(counter && (counter->sync.client == ((void
*)0)))) { ErrorFSigSafe("BUG: triggered 'if (" "!(counter && (counter->sync.client == ((void*)0)))"
")'\n"); ErrorFSigSafe("BUG: %s:%u in %s()\n", "sync.c", 120
, __func__); if (0) ErrorFSigSafe(((void*)0)); xorg_backtrace
(); } } while(0)
;
121
122 return counter->pSysCounterInfo ? counter->pSysCounterInfo->private : NULL((void*)0);
123}
124
125static Bool
126SyncCheckWarnIsCounter(const SyncObject * pSync, const char *warning)
127{
128 if (pSync && (SYNC_COUNTER0 != pSync->type)) {
129 if (SyncNumInvalidCounterWarnings++ < MAX_INVALID_COUNTER_WARNINGS5) {
130 ErrorF("%s", warning);
131 ErrorF(" Counter type: %d\n", pSync->type);
132 }
133
134 return FALSE0;
135 }
136
137 return TRUE1;
138}
139
140/* Each counter maintains a simple linked list of triggers that are
141 * interested in the counter. The two functions below are used to
142 * delete and add triggers on this list.
143 */
144void
145SyncDeleteTriggerFromSyncObject(SyncTrigger * pTrigger)
146{
147 SyncTriggerList *pCur;
148 SyncTriggerList *pPrev;
149 SyncCounter *pCounter;
150
151 /* pSync needs to be stored in pTrigger before calling here. */
152
153 if (!pTrigger->pSync)
154 return;
155
156 pPrev = NULL((void*)0);
157 pCur = pTrigger->pSync->pTriglist;
158
159 while (pCur) {
160 if (pCur->pTrigger == pTrigger) {
161 if (pPrev)
162 pPrev->next = pCur->next;
163 else
164 pTrigger->pSync->pTriglist = pCur->next;
165
166 free(pCur);
167 break;
168 }
169
170 pPrev = pCur;
171 pCur = pCur->next;
172 }
173
174 if (SYNC_COUNTER0 == pTrigger->pSync->type) {
175 pCounter = (SyncCounter *) pTrigger->pSync;
176
177 if (IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0))
)
)
178 SyncComputeBracketValues(pCounter);
179 }
180 else if (SYNC_FENCE1 == pTrigger->pSync->type) {
181 SyncFence *pFence = (SyncFence *) pTrigger->pSync;
182
183 pFence->funcs.DeleteTrigger(pTrigger);
184 }
185}
186
187int
188SyncAddTriggerToSyncObject(SyncTrigger * pTrigger)
189{
190 SyncTriggerList *pCur;
191 SyncCounter *pCounter;
192
193 if (!pTrigger->pSync)
194 return Success0;
195
196 /* don't do anything if it's already there */
197 for (pCur = pTrigger->pSync->pTriglist; pCur; pCur = pCur->next) {
198 if (pCur->pTrigger == pTrigger)
199 return Success0;
200 }
201
202 if (!(pCur = malloc(sizeof(SyncTriggerList))))
203 return BadAlloc11;
204
205 pCur->pTrigger = pTrigger;
206 pCur->next = pTrigger->pSync->pTriglist;
207 pTrigger->pSync->pTriglist = pCur;
208
209 if (SYNC_COUNTER0 == pTrigger->pSync->type) {
210 pCounter = (SyncCounter *) pTrigger->pSync;
211
212 if (IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0))
)
)
213 SyncComputeBracketValues(pCounter);
214 }
215 else if (SYNC_FENCE1 == pTrigger->pSync->type) {
216 SyncFence *pFence = (SyncFence *) pTrigger->pSync;
217
218 pFence->funcs.AddTrigger(pTrigger);
219 }
220
221 return Success0;
222}
223
224/* Below are five possible functions that can be plugged into
225 * pTrigger->CheckTrigger for counter sync objects, corresponding to
226 * the four possible test-types, and the one possible function that
227 * can be plugged into pTrigger->CheckTrigger for fence sync objects.
228 * These functions are called after the sync object's state changes
229 * but are also passed the old state so they can inspect both the old
230 * and new values. (PositiveTransition and NegativeTransition need to
231 * see both pieces of information.) These functions return the truth
232 * value of the trigger.
233 *
234 * All of them include the condition pTrigger->pSync == NULL.
235 * This is because the spec says that a trigger with a sync value
236 * of None is always TRUE.
237 */
238
239static Bool
240SyncCheckTriggerPositiveComparison(SyncTrigger * pTrigger, CARD64XSyncValue oldval)
241{
242 SyncCounter *pCounter;
243
244 /* Non-counter sync objects should never get here because they
245 * never trigger this comparison. */
246 if (!SyncCheckWarnIsCounter(pTrigger->pSync, WARN_INVALID_COUNTER_COMPARE))
247 return FALSE0;
248
249 pCounter = (SyncCounter *) pTrigger->pSync;
250
251 return (pCounter == NULL((void*)0) ||
252 XSyncValueGreaterOrEqual(pCounter->value, pTrigger->test_value)((pCounter->value).hi>(pTrigger->test_value).hi || (
(pCounter->value).hi==(pTrigger->test_value).hi &&
(pCounter->value).lo>=(pTrigger->test_value).lo))
);
253}
254
255static Bool
256SyncCheckTriggerNegativeComparison(SyncTrigger * pTrigger, CARD64XSyncValue oldval)
257{
258 SyncCounter *pCounter;
259
260 /* Non-counter sync objects should never get here because they
261 * never trigger this comparison. */
262 if (!SyncCheckWarnIsCounter(pTrigger->pSync, WARN_INVALID_COUNTER_COMPARE))
263 return FALSE0;
264
265 pCounter = (SyncCounter *) pTrigger->pSync;
266
267 return (pCounter == NULL((void*)0) ||
268 XSyncValueLessOrEqual(pCounter->value, pTrigger->test_value)((pCounter->value).hi<(pTrigger->test_value).hi || (
(pCounter->value).hi==(pTrigger->test_value).hi &&
(pCounter->value).lo<=(pTrigger->test_value).lo))
);
269}
270
271static Bool
272SyncCheckTriggerPositiveTransition(SyncTrigger * pTrigger, CARD64XSyncValue oldval)
273{
274 SyncCounter *pCounter;
275
276 /* Non-counter sync objects should never get here because they
277 * never trigger this comparison. */
278 if (!SyncCheckWarnIsCounter(pTrigger->pSync, WARN_INVALID_COUNTER_COMPARE))
279 return FALSE0;
280
281 pCounter = (SyncCounter *) pTrigger->pSync;
282
283 return (pCounter == NULL((void*)0) ||
284 (XSyncValueLessThan(oldval, pTrigger->test_value)((oldval).hi<(pTrigger->test_value).hi || ((oldval).hi==
(pTrigger->test_value).hi && (oldval).lo<(pTrigger
->test_value).lo))
&&
285 XSyncValueGreaterOrEqual(pCounter->value, pTrigger->test_value)((pCounter->value).hi>(pTrigger->test_value).hi || (
(pCounter->value).hi==(pTrigger->test_value).hi &&
(pCounter->value).lo>=(pTrigger->test_value).lo))
));
286}
287
288static Bool
289SyncCheckTriggerNegativeTransition(SyncTrigger * pTrigger, CARD64XSyncValue oldval)
290{
291 SyncCounter *pCounter;
292
293 /* Non-counter sync objects should never get here because they
294 * never trigger this comparison. */
295 if (!SyncCheckWarnIsCounter(pTrigger->pSync, WARN_INVALID_COUNTER_COMPARE))
296 return FALSE0;
297
298 pCounter = (SyncCounter *) pTrigger->pSync;
299
300 return (pCounter == NULL((void*)0) ||
301 (XSyncValueGreaterThan(oldval, pTrigger->test_value)((oldval).hi>(pTrigger->test_value).hi || ((oldval).hi==
(pTrigger->test_value).hi && (oldval).lo>(pTrigger
->test_value).lo))
&&
302 XSyncValueLessOrEqual(pCounter->value, pTrigger->test_value)((pCounter->value).hi<(pTrigger->test_value).hi || (
(pCounter->value).hi==(pTrigger->test_value).hi &&
(pCounter->value).lo<=(pTrigger->test_value).lo))
));
303}
304
305static Bool
306SyncCheckTriggerFence(SyncTrigger * pTrigger, CARD64XSyncValue unused)
307{
308 SyncFence *pFence = (SyncFence *) pTrigger->pSync;
309
310 (void) unused;
311
312 return (pFence == NULL((void*)0) || pFence->funcs.CheckTriggered(pFence));
313}
314
315static int
316SyncInitTrigger(ClientPtr client, SyncTrigger * pTrigger, XID syncObject,
317 RESTYPE resType, Mask changes)
318{
319 SyncObject *pSync = pTrigger->pSync;
320 SyncCounter *pCounter = NULL((void*)0);
321 int rc;
322 Bool newSyncObject = FALSE0;
323
324 if (changes & XSyncCACounter(1L<<0)) {
325 if (syncObject == None0L)
326 pSync = NULL((void*)0);
327 else if (Success0 != (rc = dixLookupResourceByType((void **) &pSync,
328 syncObject, resType,
329 client,
330 DixReadAccess(1<<0)))) {
331 client->errorValue = syncObject;
332 return rc;
333 }
334 if (pSync != pTrigger->pSync) { /* new counter for trigger */
335 SyncDeleteTriggerFromSyncObject(pTrigger);
336 pTrigger->pSync = pSync;
337 newSyncObject = TRUE1;
338 }
339 }
340
341 /* if system counter, ask it what the current value is */
342
343 if (pSync && SYNC_COUNTER0 == pSync->type) {
344 pCounter = (SyncCounter *) pSync;
345
346 if (IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0))
)
) {
347 (*pCounter->pSysCounterInfo->QueryValue) ((void *) pCounter,
348 &pCounter->value);
349 }
350 }
351
352 if (changes & XSyncCAValueType(1L<<1)) {
353 if (pTrigger->value_type != XSyncRelative &&
354 pTrigger->value_type != XSyncAbsolute) {
355 client->errorValue = pTrigger->value_type;
356 return BadValue2;
357 }
358 }
359
360 if (changes & XSyncCATestType(1L<<3)) {
361
362 if (pSync && SYNC_FENCE1 == pSync->type) {
363 pTrigger->CheckTrigger = SyncCheckTriggerFence;
364 }
365 else {
366 /* select appropriate CheckTrigger function */
367
368 switch (pTrigger->test_type) {
369 case XSyncPositiveTransition:
370 pTrigger->CheckTrigger = SyncCheckTriggerPositiveTransition;
371 break;
372 case XSyncNegativeTransition:
373 pTrigger->CheckTrigger = SyncCheckTriggerNegativeTransition;
374 break;
375 case XSyncPositiveComparison:
376 pTrigger->CheckTrigger = SyncCheckTriggerPositiveComparison;
377 break;
378 case XSyncNegativeComparison:
379 pTrigger->CheckTrigger = SyncCheckTriggerNegativeComparison;
380 break;
381 default:
382 client->errorValue = pTrigger->test_type;
383 return BadValue2;
384 }
385 }
386 }
387
388 if (changes & (XSyncCAValueType(1L<<1) | XSyncCAValue(1L<<2))) {
389 if (pTrigger->value_type == XSyncAbsolute)
390 pTrigger->test_value = pTrigger->wait_value;
391 else { /* relative */
392
393 Bool overflow;
394
395 if (pCounter == NULL((void*)0))
396 return BadMatch8;
397
398 XSyncValueAdd(&pTrigger->test_value, pCounter->value,{ int t = (pCounter->value).lo; Bool signa = (((pCounter->
value).hi & 0x80000000) ? 1 : 0); Bool signb = (((pTrigger
->wait_value).hi & 0x80000000) ? 1 : 0); ((&pTrigger
->test_value)->lo = (pCounter->value).lo + (pTrigger
->wait_value).lo); ((&pTrigger->test_value)->hi =
(pCounter->value).hi + (pTrigger->wait_value).hi); if (
t>(&pTrigger->test_value)->lo) (&pTrigger->
test_value)->hi++; *&overflow = ((signa == signb) &&
!(signa == (((*&pTrigger->test_value).hi & 0x80000000
) ? 1 : 0))); }
399 pTrigger->wait_value, &overflow){ int t = (pCounter->value).lo; Bool signa = (((pCounter->
value).hi & 0x80000000) ? 1 : 0); Bool signb = (((pTrigger
->wait_value).hi & 0x80000000) ? 1 : 0); ((&pTrigger
->test_value)->lo = (pCounter->value).lo + (pTrigger
->wait_value).lo); ((&pTrigger->test_value)->hi =
(pCounter->value).hi + (pTrigger->wait_value).hi); if (
t>(&pTrigger->test_value)->lo) (&pTrigger->
test_value)->hi++; *&overflow = ((signa == signb) &&
!(signa == (((*&pTrigger->test_value).hi & 0x80000000
) ? 1 : 0))); }
;
400 if (overflow) {
401 client->errorValue = XSyncValueHigh32(pTrigger->wait_value)((pTrigger->wait_value).hi);
402 return BadValue2;
403 }
404 }
405 }
406
407 /* we wait until we're sure there are no errors before registering
408 * a new counter on a trigger
409 */
410 if (newSyncObject) {
411 if ((rc = SyncAddTriggerToSyncObject(pTrigger)) != Success0)
412 return rc;
413 }
414 else if (pCounter && IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0))
)
) {
415 SyncComputeBracketValues(pCounter);
416 }
417
418 return Success0;
419}
420
421/* AlarmNotify events happen in response to actions taken on an Alarm or
422 * the counter used by the alarm. AlarmNotify may be sent to multiple
423 * clients. The alarm maintains a list of clients interested in events.
424 */
425static void
426SyncSendAlarmNotifyEvents(SyncAlarm * pAlarm)
427{
428 SyncAlarmClientList *pcl;
429 xSyncAlarmNotifyEvent ane;
430 SyncTrigger *pTrigger = &pAlarm->trigger;
431 SyncCounter *pCounter;
432
433 if (!SyncCheckWarnIsCounter(pTrigger->pSync, WARN_INVALID_COUNTER_ALARM))
434 return;
435
436 pCounter = (SyncCounter *) pTrigger->pSync;
437
438 UpdateCurrentTime();
439
440 ane = (xSyncAlarmNotifyEvent) {
441 .type = SyncEventBase + XSyncAlarmNotify1,
442 .kind = XSyncAlarmNotify1,
443 .alarm = pAlarm->alarm_id,
444 .alarm_value_hi = XSyncValueHigh32(pTrigger->test_value)((pTrigger->test_value).hi),
445 .alarm_value_lo = XSyncValueLow32(pTrigger->test_value)((pTrigger->test_value).lo),
446 .time = currentTime.milliseconds,
447 .state = pAlarm->state
448 };
449
450 if (pTrigger->pSync && SYNC_COUNTER0 == pTrigger->pSync->type) {
451 ane.counter_value_hi = XSyncValueHigh32(pCounter->value)((pCounter->value).hi);
452 ane.counter_value_lo = XSyncValueLow32(pCounter->value)((pCounter->value).lo);
453 }
454 else {
455 /* XXX what else can we do if there's no counter? */
456 ane.counter_value_hi = ane.counter_value_lo = 0;
457 }
458
459 /* send to owner */
460 if (pAlarm->events)
461 WriteEventsToClient(pAlarm->client, 1, (xEvent *) &ane);
462
463 /* send to other interested clients */
464 for (pcl = pAlarm->pEventClients; pcl; pcl = pcl->next)
465 WriteEventsToClient(pcl->client, 1, (xEvent *) &ane);
466}
467
468/* CounterNotify events only occur in response to an Await. The events
469 * go only to the Awaiting client.
470 */
471static void
472SyncSendCounterNotifyEvents(ClientPtr client, SyncAwait ** ppAwait,
473 int num_events)
474{
475 xSyncCounterNotifyEvent *pEvents, *pev;
476 int i;
477
478 if (client->clientGone)
479 return;
480 pev = pEvents = calloc(num_events, sizeof(xSyncCounterNotifyEvent));
481 if (!pEvents)
482 return;
483 UpdateCurrentTime();
484 for (i = 0; i < num_events; i++, ppAwait++, pev++) {
485 SyncTrigger *pTrigger = &(*ppAwait)->trigger;
486
487 pev->type = SyncEventBase + XSyncCounterNotify0;
488 pev->kind = XSyncCounterNotify0;
489 pev->counter = pTrigger->pSync->id;
490 pev->wait_value_lo = XSyncValueLow32(pTrigger->test_value)((pTrigger->test_value).lo);
491 pev->wait_value_hi = XSyncValueHigh32(pTrigger->test_value)((pTrigger->test_value).hi);
492 if (SYNC_COUNTER0 == pTrigger->pSync->type) {
493 SyncCounter *pCounter = (SyncCounter *) pTrigger->pSync;
494
495 pev->counter_value_lo = XSyncValueLow32(pCounter->value)((pCounter->value).lo);
496 pev->counter_value_hi = XSyncValueHigh32(pCounter->value)((pCounter->value).hi);
497 }
498 else {
499 pev->counter_value_lo = 0;
500 pev->counter_value_hi = 0;
501 }
502
503 pev->time = currentTime.milliseconds;
504 pev->count = num_events - i - 1; /* events remaining */
505 pev->destroyed = pTrigger->pSync->beingDestroyed;
506 }
507 /* swapping will be taken care of by this */
508 WriteEventsToClient(client, num_events, (xEvent *) pEvents);
509 free(pEvents);
510}
511
512/* This function is called when an alarm's counter is destroyed.
513 * It is plugged into pTrigger->CounterDestroyed (for alarm triggers).
514 */
515static void
516SyncAlarmCounterDestroyed(SyncTrigger * pTrigger)
517{
518 SyncAlarm *pAlarm = (SyncAlarm *) pTrigger;
519
520 pAlarm->state = XSyncAlarmInactive;
521 SyncSendAlarmNotifyEvents(pAlarm);
522 pTrigger->pSync = NULL((void*)0);
523}
524
525/* This function is called when an alarm "goes off."
526 * It is plugged into pTrigger->TriggerFired (for alarm triggers).
527 */
528static void
529SyncAlarmTriggerFired(SyncTrigger * pTrigger)
530{
531 SyncAlarm *pAlarm = (SyncAlarm *) pTrigger;
532 SyncCounter *pCounter;
533 CARD64XSyncValue new_test_value;
534
535 if (!SyncCheckWarnIsCounter(pTrigger->pSync, WARN_INVALID_COUNTER_ALARM))
536 return;
537
538 pCounter = (SyncCounter *) pTrigger->pSync;
539
540 /* no need to check alarm unless it's active */
541 if (pAlarm->state != XSyncAlarmActive)
542 return;
543
544 /* " if the counter value is None, or if the delta is 0 and
545 * the test-type is PositiveComparison or NegativeComparison,
546 * no change is made to value (test-value) and the alarm
547 * state is changed to Inactive before the event is generated."
548 */
549 if (pCounter == NULL((void*)0) || (XSyncValueIsZero(pAlarm->delta)((pAlarm->delta).lo==0 && (pAlarm->delta).hi==0
)
550 && (pAlarm->trigger.test_type ==
551 XSyncPositiveComparison ||
552 pAlarm->trigger.test_type ==
553 XSyncNegativeComparison)))
554 pAlarm->state = XSyncAlarmInactive;
555
556 new_test_value = pAlarm->trigger.test_value;
557
558 if (pAlarm->state == XSyncAlarmActive) {
559 Bool overflow;
560 CARD64XSyncValue oldvalue;
561 SyncTrigger *paTrigger = &pAlarm->trigger;
562 SyncCounter *paCounter;
563
564 if (!SyncCheckWarnIsCounter(paTrigger->pSync,
565 WARN_INVALID_COUNTER_ALARM))
566 return;
567
568 paCounter = (SyncCounter *) pTrigger->pSync;
569
570 /* "The alarm is updated by repeatedly adding delta to the
571 * value of the trigger and re-initializing it until it
572 * becomes FALSE."
573 */
574 oldvalue = paTrigger->test_value;
575
576 /* XXX really should do something smarter here */
577
578 do {
579 XSyncValueAdd(&paTrigger->test_value, paTrigger->test_value,{ int t = (paTrigger->test_value).lo; Bool signa = (((paTrigger
->test_value).hi & 0x80000000) ? 1 : 0); Bool signb = (
((pAlarm->delta).hi & 0x80000000) ? 1 : 0); ((&paTrigger
->test_value)->lo = (paTrigger->test_value).lo + (pAlarm
->delta).lo); ((&paTrigger->test_value)->hi = (paTrigger
->test_value).hi + (pAlarm->delta).hi); if (t>(&
paTrigger->test_value)->lo) (&paTrigger->test_value
)->hi++; *&overflow = ((signa == signb) && !(signa
== (((*&paTrigger->test_value).hi & 0x80000000) ?
1 : 0))); }
580 pAlarm->delta, &overflow){ int t = (paTrigger->test_value).lo; Bool signa = (((paTrigger
->test_value).hi & 0x80000000) ? 1 : 0); Bool signb = (
((pAlarm->delta).hi & 0x80000000) ? 1 : 0); ((&paTrigger
->test_value)->lo = (paTrigger->test_value).lo + (pAlarm
->delta).lo); ((&paTrigger->test_value)->hi = (paTrigger
->test_value).hi + (pAlarm->delta).hi); if (t>(&
paTrigger->test_value)->lo) (&paTrigger->test_value
)->hi++; *&overflow = ((signa == signb) && !(signa
== (((*&paTrigger->test_value).hi & 0x80000000) ?
1 : 0))); }
;
581 } while (!overflow &&
582 (*paTrigger->CheckTrigger) (paTrigger, paCounter->value));
583
584 new_test_value = paTrigger->test_value;
585 paTrigger->test_value = oldvalue;
586
587 /* "If this update would cause value to fall outside the range
588 * for an INT64...no change is made to value (test-value) and
589 * the alarm state is changed to Inactive before the event is
590 * generated."
591 */
592 if (overflow) {
593 new_test_value = oldvalue;
594 pAlarm->state = XSyncAlarmInactive;
595 }
596 }
597 /* The AlarmNotify event has to have the "new state of the alarm"
598 * which we can't be sure of until this point. However, it has
599 * to have the "old" trigger test value. That's the reason for
600 * all the newvalue/oldvalue shuffling above. After we send the
601 * events, give the trigger its new test value.
602 */
603 SyncSendAlarmNotifyEvents(pAlarm);
604 pTrigger->test_value = new_test_value;
605}
606
607/* This function is called when an Await unblocks, either as a result
608 * of the trigger firing OR the counter being destroyed.
609 * It goes into pTrigger->TriggerFired AND pTrigger->CounterDestroyed
610 * (for Await triggers).
611 */
612static void
613SyncAwaitTriggerFired(SyncTrigger * pTrigger)
614{
615 SyncAwait *pAwait = (SyncAwait *) pTrigger;
616 int numwaits;
617 SyncAwaitUnion *pAwaitUnion;
618 SyncAwait **ppAwait;
619 int num_events = 0;
620
621 pAwaitUnion = (SyncAwaitUnion *) pAwait->pHeader;
622 numwaits = pAwaitUnion->header.num_waitconditions;
623 ppAwait = xallocarray(numwaits, sizeof(SyncAwait *))xreallocarray(((void*)0), (numwaits), (sizeof(SyncAwait *)));
624 if (!ppAwait)
625 goto bail;
626
627 pAwait = &(pAwaitUnion + 1)->await;
628
629 /* "When a client is unblocked, all the CounterNotify events for
630 * the Await request are generated contiguously. If count is 0
631 * there are no more events to follow for this request. If
632 * count is n, there are at least n more events to follow."
633 *
634 * Thus, it is best to find all the counters for which events
635 * need to be sent first, so that an accurate count field can
636 * be stored in the events.
637 */
638 for (; numwaits; numwaits--, pAwait++) {
639 CARD64XSyncValue diff;
640 Bool overflow, diffgreater, diffequal;
641
642 /* "A CounterNotify event with the destroyed flag set to TRUE is
643 * always generated if the counter for one of the triggers is
644 * destroyed."
645 */
646 if (pAwait->trigger.pSync->beingDestroyed) {
647 ppAwait[num_events++] = pAwait;
648 continue;
649 }
650
651 if (SYNC_COUNTER0 == pAwait->trigger.pSync->type) {
652 SyncCounter *pCounter = (SyncCounter *) pAwait->trigger.pSync;
653
654 /* "The difference between the counter and the test value is
655 * calculated by subtracting the test value from the value of
656 * the counter."
657 */
658 XSyncValueSubtract(&diff, pCounter->value,{ int t = (pCounter->value).lo; Bool signa = (((pCounter->
value).hi & 0x80000000) ? 1 : 0); Bool signb = (((pAwait->
trigger.test_value).hi & 0x80000000) ? 1 : 0); ((&diff
)->lo = (pCounter->value).lo - (pAwait->trigger.test_value
).lo); ((&diff)->hi = (pCounter->value).hi - (pAwait
->trigger.test_value).hi); if (t<(&diff)->lo) (&
diff)->hi--; *&overflow = ((signa == signb) &&
!(signa == (((*&diff).hi & 0x80000000) ? 1 : 0))); }
659 pAwait->trigger.test_value, &overflow){ int t = (pCounter->value).lo; Bool signa = (((pCounter->
value).hi & 0x80000000) ? 1 : 0); Bool signb = (((pAwait->
trigger.test_value).hi & 0x80000000) ? 1 : 0); ((&diff
)->lo = (pCounter->value).lo - (pAwait->trigger.test_value
).lo); ((&diff)->hi = (pCounter->value).hi - (pAwait
->trigger.test_value).hi); if (t<(&diff)->lo) (&
diff)->hi--; *&overflow = ((signa == signb) &&
!(signa == (((*&diff).hi & 0x80000000) ? 1 : 0))); }
;
660
661 /* "If the difference lies outside the range for an INT64, an
662 * event is not generated."
663 */
664 if (overflow)
665 continue;
666 diffgreater = XSyncValueGreaterThan(diff, pAwait->event_threshold)((diff).hi>(pAwait->event_threshold).hi || ((diff).hi==
(pAwait->event_threshold).hi && (diff).lo>(pAwait
->event_threshold).lo))
;
667 diffequal = XSyncValueEqual(diff, pAwait->event_threshold)((diff).lo==(pAwait->event_threshold).lo && (diff)
.hi==(pAwait->event_threshold).hi)
;
668
669 /* "If the test-type is PositiveTransition or
670 * PositiveComparison, a CounterNotify event is generated if
671 * the difference is at least event-threshold. If the test-type
672 * is NegativeTransition or NegativeComparison, a CounterNotify
673 * event is generated if the difference is at most
674 * event-threshold."
675 */
676
677 if (((pAwait->trigger.test_type == XSyncPositiveComparison ||
678 pAwait->trigger.test_type == XSyncPositiveTransition)
679 && (diffgreater || diffequal))
680 ||
681 ((pAwait->trigger.test_type == XSyncNegativeComparison ||
682 pAwait->trigger.test_type == XSyncNegativeTransition)
683 && (!diffgreater) /* less or equal */
684 )
685 ) {
686 ppAwait[num_events++] = pAwait;
687 }
688 }
689 }
690 if (num_events)
691 SyncSendCounterNotifyEvents(pAwaitUnion->header.client, ppAwait,
692 num_events);
693 free(ppAwait);
694
695 bail:
696 /* unblock the client */
697 AttendClient(pAwaitUnion->header.client);
698 /* delete the await */
699 FreeResource(pAwaitUnion->header.delete_id, RT_NONE((RESTYPE)0));
700}
701
702static CARD64XSyncValue
703SyncUpdateCounter(SyncCounter *pCounter, CARD64XSyncValue newval)
704{
705 CARD64XSyncValue oldval = pCounter->value;
706 pCounter->value = newval;
707 return oldval;
708}
709
710/* This function should always be used to change a counter's value so that
711 * any triggers depending on the counter will be checked.
712 */
713void
714SyncChangeCounter(SyncCounter * pCounter, CARD64XSyncValue newval)
715{
716 SyncTriggerList *ptl, *pnext;
717 CARD64XSyncValue oldval;
718
719 oldval = SyncUpdateCounter(pCounter, newval);
720
721 /* run through triggers to see if any become true */
722 for (ptl = pCounter->sync.pTriglist; ptl; ptl = pnext) {
723 pnext = ptl->next;
724 if ((*ptl->pTrigger->CheckTrigger) (ptl->pTrigger, oldval))
725 (*ptl->pTrigger->TriggerFired) (ptl->pTrigger);
726 }
727
728 if (IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0))
)
) {
729 SyncComputeBracketValues(pCounter);
730 }
731}
732
733/* loosely based on dix/events.c/EventSelectForWindow */
734static Bool
735SyncEventSelectForAlarm(SyncAlarm * pAlarm, ClientPtr client, Bool wantevents)
736{
737 SyncAlarmClientList *pClients;
738
739 if (client == pAlarm->client) { /* alarm owner */
740 pAlarm->events = wantevents;
741 return Success0;
742 }
743
744 /* see if the client is already on the list (has events selected) */
745
746 for (pClients = pAlarm->pEventClients; pClients; pClients = pClients->next) {
747 if (pClients->client == client) {
748 /* client's presence on the list indicates desire for
749 * events. If the client doesn't want events, remove it
750 * from the list. If the client does want events, do
751 * nothing, since it's already got them.
752 */
753 if (!wantevents) {
754 FreeResource(pClients->delete_id, RT_NONE((RESTYPE)0));
755 }
756 return Success0;
757 }
758 }
759
760 /* if we get here, this client does not currently have
761 * events selected on the alarm
762 */
763
764 if (!wantevents)
765 /* client doesn't want events, and we just discovered that it
766 * doesn't have them, so there's nothing to do.
767 */
768 return Success0;
769
770 /* add new client to pAlarm->pEventClients */
771
772 pClients = malloc(sizeof(SyncAlarmClientList));
773 if (!pClients)
774 return BadAlloc11;
775
776 /* register it as a resource so it will be cleaned up
777 * if the client dies
778 */
779
780 pClients->delete_id = FakeClientID(client->index);
781
782 /* link it into list after we know all the allocations succeed */
783 pClients->next = pAlarm->pEventClients;
784 pAlarm->pEventClients = pClients;
785 pClients->client = client;
786
787 if (!AddResourceDarwin_X_AddResource(pClients->delete_id, RTAlarmClient, pAlarm))
788 return BadAlloc11;
789
790 return Success0;
791}
792
793/*
794 * ** SyncChangeAlarmAttributes ** This is used by CreateAlarm and ChangeAlarm
795 */
796static int
797SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm * pAlarm, Mask mask,
798 CARD32 *values)
799{
800 int status;
801 XSyncCounter counter;
802 Mask origmask = mask;
803
804 counter = pAlarm->trigger.pSync ? pAlarm->trigger.pSync->id : None0L;
805
806 while (mask) {
807 int index2 = lowbit(mask)((mask) & (~(mask) + 1));
808
809 mask &= ~index2;
810 switch (index2) {
811 case XSyncCACounter(1L<<0):
812 mask &= ~XSyncCACounter(1L<<0);
813 /* sanity check in SyncInitTrigger */
814 counter = *values++;
815 break;
816
817 case XSyncCAValueType(1L<<1):
818 mask &= ~XSyncCAValueType(1L<<1);
819 /* sanity check in SyncInitTrigger */
820 pAlarm->trigger.value_type = *values++;
821 break;
822
823 case XSyncCAValue(1L<<2):
824 mask &= ~XSyncCAValue(1L<<2);
825 XSyncIntsToValue(&pAlarm->trigger.wait_value, values[1], values[0])((&pAlarm->trigger.wait_value)->lo = (values[1]), (
&pAlarm->trigger.wait_value)->hi = (values[0]))
;
826 values += 2;
827 break;
828
829 case XSyncCATestType(1L<<3):
830 mask &= ~XSyncCATestType(1L<<3);
831 /* sanity check in SyncInitTrigger */
832 pAlarm->trigger.test_type = *values++;
833 break;
834
835 case XSyncCADelta(1L<<4):
836 mask &= ~XSyncCADelta(1L<<4);
837 XSyncIntsToValue(&pAlarm->delta, values[1], values[0])((&pAlarm->delta)->lo = (values[1]), (&pAlarm->
delta)->hi = (values[0]))
;
838 values += 2;
839 break;
840
841 case XSyncCAEvents(1L<<5):
842 mask &= ~XSyncCAEvents(1L<<5);
843 if ((*values != xTrue1) && (*values != xFalse0)) {
844 client->errorValue = *values;
845 return BadValue2;
846 }
847 status = SyncEventSelectForAlarm(pAlarm, client,
848 (Bool) (*values++));
849 if (status != Success0)
850 return status;
851 break;
852
853 default:
854 client->errorValue = mask;
855 return BadValue2;
856 }
857 }
858
859 /* "If the test-type is PositiveComparison or PositiveTransition
860 * and delta is less than zero, or if the test-type is
861 * NegativeComparison or NegativeTransition and delta is
862 * greater than zero, a Match error is generated."
863 */
864 if (origmask & (XSyncCADelta(1L<<4) | XSyncCATestType(1L<<3))) {
865 CARD64XSyncValue zero;
866
867 XSyncIntToValue(&zero, 0)((&zero)->hi=((0<0)?~0:0),(&zero)->lo=(0));
868 if ((((pAlarm->trigger.test_type == XSyncPositiveComparison) ||
869 (pAlarm->trigger.test_type == XSyncPositiveTransition))
870 && XSyncValueLessThan(pAlarm->delta, zero)((pAlarm->delta).hi<(zero).hi || ((pAlarm->delta).hi
==(zero).hi && (pAlarm->delta).lo<(zero).lo))
)
871 ||
872 (((pAlarm->trigger.test_type == XSyncNegativeComparison) ||
873 (pAlarm->trigger.test_type == XSyncNegativeTransition))
874 && XSyncValueGreaterThan(pAlarm->delta, zero)((pAlarm->delta).hi>(zero).hi || ((pAlarm->delta).hi
==(zero).hi && (pAlarm->delta).lo>(zero).lo))
)
875 ) {
876 return BadMatch8;
877 }
878 }
879
880 /* postpone this until now, when we're sure nothing else can go wrong */
881 if ((status = SyncInitTrigger(client, &pAlarm->trigger, counter, RTCounter,
882 origmask & XSyncCAAllTrigger((1L<<0) | (1L<<1) | (1L<<2) | (1L<<3
))
)) != Success0)
883 return status;
884
885 /* XXX spec does not really say to do this - needs clarification */
886 pAlarm->state = XSyncAlarmActive;
887 return Success0;
888}
889
890static SyncObject *
891SyncCreate(ClientPtr client, XID id, unsigned char type)
892{
893 SyncObject *pSync;
894
895 switch (type) {
896 case SYNC_COUNTER0:
897 pSync = malloc(sizeof(SyncCounter));
898 break;
899 case SYNC_FENCE1:
900 pSync = (SyncObject *) dixAllocateObjectWithPrivates(SyncFence,(SyncFence *) _dixAllocateObjectWithPrivates(sizeof(SyncFence
), sizeof(SyncFence), __builtin_offsetof(SyncFence, devPrivates
), PRIVATE_SYNC_FENCE)
901 PRIVATE_SYNC_FENCE)(SyncFence *) _dixAllocateObjectWithPrivates(sizeof(SyncFence
), sizeof(SyncFence), __builtin_offsetof(SyncFence, devPrivates
), PRIVATE_SYNC_FENCE)
;
902 break;
903 default:
904 return NULL((void*)0);
905 }
906
907 if (!pSync)
908 return NULL((void*)0);
909
910 pSync->client = client;
911 pSync->id = id;
912 pSync->pTriglist = NULL((void*)0);
913 pSync->beingDestroyed = FALSE0;
914 pSync->type = type;
915
916 return pSync;
917}
918
919int
920SyncCreateFenceFromFD(ClientPtr client, DrawablePtr pDraw, XID id, int fd, BOOL initially_triggered)
921{
922#if HAVE_XSHMFENCE1
923 SyncFence *pFence;
924 int status;
925
926 pFence = (SyncFence *) SyncCreate(client, id, SYNC_FENCE1);
927 if (!pFence)
928 return BadAlloc11;
929
930 status = miSyncInitFenceFromFD(pDraw, pFence, fd, initially_triggered);
931 if (status != Success0) {
932 dixFreeObjectWithPrivates(pFence, PRIVATE_SYNC_FENCE)_dixFreeObjectWithPrivates(pFence, (pFence)->devPrivates, PRIVATE_SYNC_FENCE
)
;
933 return status;
934 }
935
936 if (!AddResourceDarwin_X_AddResource(id, RTFence, (void *) pFence))
937 return BadAlloc11;
938
939 return Success0;
940#else
941 return BadImplementation17;
942#endif
943}
944
945int
946SyncFDFromFence(ClientPtr client, DrawablePtr pDraw, SyncFence *pFence)
947{
948#if HAVE_XSHMFENCE1
949 return miSyncFDFromFence(pDraw, pFence);
950#else
951 return BadImplementation17;
952#endif
953}
954
955static SyncCounter *
956SyncCreateCounter(ClientPtr client, XSyncCounter id, CARD64XSyncValue initialvalue)
957{
958 SyncCounter *pCounter;
959
960 if (!(pCounter = (SyncCounter *) SyncCreate(client, id, SYNC_COUNTER0)))
961 return NULL((void*)0);
962
963 pCounter->value = initialvalue;
964 pCounter->pSysCounterInfo = NULL((void*)0);
965
966 if (!AddResourceDarwin_X_AddResource(id, RTCounter, (void *) pCounter))
967 return NULL((void*)0);
968
969 return pCounter;
970}
971
972static int FreeCounter(void *, XID);
973
974/*
975 * ***** System Counter utilities
976 */
977
978SyncCounter*
979SyncCreateSystemCounter(const char *name,
980 CARD64XSyncValue initial,
981 CARD64XSyncValue resolution,
982 SyncCounterType counterType,
983 SyncSystemCounterQueryValue QueryValue,
984 SyncSystemCounterBracketValues BracketValues
985 )
986{
987 SyncCounter *pCounter = SyncCreateCounter(NULL((void*)0), FakeClientID(0), initial);
988
989 if (pCounter) {
990 SysCounterInfo *psci;
991
992 psci = malloc(sizeof(SysCounterInfo));
993 if (!psci) {
994 FreeResource(pCounter->sync.id, RT_NONE((RESTYPE)0));
995 return pCounter;
996 }
997 pCounter->pSysCounterInfo = psci;
998 psci->pCounter = pCounter;
999 psci->name = strdup(name);
1000 psci->resolution = resolution;
1001 psci->counterType = counterType;
1002 psci->QueryValue = QueryValue;
1003 psci->BracketValues = BracketValues;
1004 psci->private = NULL((void*)0);
1005 XSyncMaxValue(&psci->bracket_greater)((&psci->bracket_greater)->hi = 0x7fffffff, (&psci
->bracket_greater)->lo = 0xffffffff)
;
1006 XSyncMinValue(&psci->bracket_less)((&psci->bracket_less)->hi = 0x80000000, (&psci
->bracket_less)->lo = 0)
;
1007 xorg_list_add(&psci->entry, &SysCounterList);
1008 }
1009 return pCounter;
1010}
1011
1012void
1013SyncDestroySystemCounter(void *pSysCounter)
1014{
1015 SyncCounter *pCounter = (SyncCounter *) pSysCounter;
1016
1017 FreeResource(pCounter->sync.id, RT_NONE((RESTYPE)0));
1018}
1019
1020static void
1021SyncComputeBracketValues(SyncCounter * pCounter)
1022{
1023 SyncTriggerList *pCur;
1024 SyncTrigger *pTrigger;
1025 SysCounterInfo *psci;
1026 CARD64XSyncValue *pnewgtval = NULL((void*)0);
1027 CARD64XSyncValue *pnewltval = NULL((void*)0);
1028 SyncCounterType ct;
1029
1030 if (!pCounter)
1031 return;
1032
1033 psci = pCounter->pSysCounterInfo;
1034 ct = pCounter->pSysCounterInfo->counterType;
1035 if (ct == XSyncCounterNeverChanges)
1036 return;
1037
1038 XSyncMaxValue(&psci->bracket_greater)((&psci->bracket_greater)->hi = 0x7fffffff, (&psci
->bracket_greater)->lo = 0xffffffff)
;
1039 XSyncMinValue(&psci->bracket_less)((&psci->bracket_less)->hi = 0x80000000, (&psci
->bracket_less)->lo = 0)
;
1040
1041 for (pCur = pCounter->sync.pTriglist; pCur; pCur = pCur->next) {
1042 pTrigger = pCur->pTrigger;
1043
1044 if (pTrigger->test_type == XSyncPositiveComparison &&
1045 ct != XSyncCounterNeverIncreases) {
1046 if (XSyncValueLessThan(pCounter->value, pTrigger->test_value)((pCounter->value).hi<(pTrigger->test_value).hi || (
(pCounter->value).hi==(pTrigger->test_value).hi &&
(pCounter->value).lo<(pTrigger->test_value).lo))
&&
1047 XSyncValueLessThan(pTrigger->test_value,((pTrigger->test_value).hi<(psci->bracket_greater).hi
|| ((pTrigger->test_value).hi==(psci->bracket_greater)
.hi && (pTrigger->test_value).lo<(psci->bracket_greater
).lo))
1048 psci->bracket_greater)((pTrigger->test_value).hi<(psci->bracket_greater).hi
|| ((pTrigger->test_value).hi==(psci->bracket_greater)
.hi && (pTrigger->test_value).lo<(psci->bracket_greater
).lo))
) {
1049 psci->bracket_greater = pTrigger->test_value;
1050 pnewgtval = &psci->bracket_greater;
1051 }
1052 else if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value)((pCounter->value).hi>(pTrigger->test_value).hi || (
(pCounter->value).hi==(pTrigger->test_value).hi &&
(pCounter->value).lo>(pTrigger->test_value).lo))
&&
1053 XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)((pTrigger->test_value).hi>(psci->bracket_less).hi ||
((pTrigger->test_value).hi==(psci->bracket_less).hi &&
(pTrigger->test_value).lo>(psci->bracket_less).lo))
) {
1054 psci->bracket_less = pTrigger->test_value;
1055 pnewltval = &psci->bracket_less;
1056 }
1057 }
1058 else if (pTrigger->test_type == XSyncNegativeComparison &&
1059 ct != XSyncCounterNeverDecreases) {
1060 if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value)((pCounter->value).hi>(pTrigger->test_value).hi || (
(pCounter->value).hi==(pTrigger->test_value).hi &&
(pCounter->value).lo>(pTrigger->test_value).lo))
&&
1061 XSyncValueGreaterThan(pTrigger->test_value,((pTrigger->test_value).hi>(psci->bracket_less).hi ||
((pTrigger->test_value).hi==(psci->bracket_less).hi &&
(pTrigger->test_value).lo>(psci->bracket_less).lo))
1062 psci->bracket_less)((pTrigger->test_value).hi>(psci->bracket_less).hi ||
((pTrigger->test_value).hi==(psci->bracket_less).hi &&
(pTrigger->test_value).lo>(psci->bracket_less).lo))
) {
1063 psci->bracket_less = pTrigger->test_value;
1064 pnewltval = &psci->bracket_less;
1065 }
1066 else if (XSyncValueLessThan(pCounter->value, pTrigger->test_value)((pCounter->value).hi<(pTrigger->test_value).hi || (
(pCounter->value).hi==(pTrigger->test_value).hi &&
(pCounter->value).lo<(pTrigger->test_value).lo))
&&
1067 XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)((pTrigger->test_value).hi<(psci->bracket_greater).hi
|| ((pTrigger->test_value).hi==(psci->bracket_greater)
.hi && (pTrigger->test_value).lo<(psci->bracket_greater
).lo))
) {
1068 psci->bracket_greater = pTrigger->test_value;
1069 pnewgtval = &psci->bracket_greater;
1070 }
1071 }
1072 else if (pTrigger->test_type == XSyncNegativeTransition &&
1073 ct != XSyncCounterNeverIncreases) {
1074 if (XSyncValueGreaterOrEqual(pCounter->value, pTrigger->test_value)((pCounter->value).hi>(pTrigger->test_value).hi || (
(pCounter->value).hi==(pTrigger->test_value).hi &&
(pCounter->value).lo>=(pTrigger->test_value).lo))
&&
1075 XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)((pTrigger->test_value).hi>(psci->bracket_less).hi ||
((pTrigger->test_value).hi==(psci->bracket_less).hi &&
(pTrigger->test_value).lo>(psci->bracket_less).lo))
) {
1076 /*
1077 * If the value is exactly equal to our threshold, we want one
1078 * more event in the negative direction to ensure we pick up
1079 * when the value is less than this threshold.
1080 */
1081 psci->bracket_less = pTrigger->test_value;
1082 pnewltval = &psci->bracket_less;
1083 }
1084 else if (XSyncValueLessThan(pCounter->value, pTrigger->test_value)((pCounter->value).hi<(pTrigger->test_value).hi || (
(pCounter->value).hi==(pTrigger->test_value).hi &&
(pCounter->value).lo<(pTrigger->test_value).lo))
&&
1085 XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)((pTrigger->test_value).hi<(psci->bracket_greater).hi
|| ((pTrigger->test_value).hi==(psci->bracket_greater)
.hi && (pTrigger->test_value).lo<(psci->bracket_greater
).lo))
) {
1086 psci->bracket_greater = pTrigger->test_value;
1087 pnewgtval = &psci->bracket_greater;
1088 }
1089 }
1090 else if (pTrigger->test_type == XSyncPositiveTransition &&
1091 ct != XSyncCounterNeverDecreases) {
1092 if (XSyncValueLessOrEqual(pCounter->value, pTrigger->test_value)((pCounter->value).hi<(pTrigger->test_value).hi || (
(pCounter->value).hi==(pTrigger->test_value).hi &&
(pCounter->value).lo<=(pTrigger->test_value).lo))
&&
1093 XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)((pTrigger->test_value).hi<(psci->bracket_greater).hi
|| ((pTrigger->test_value).hi==(psci->bracket_greater)
.hi && (pTrigger->test_value).lo<(psci->bracket_greater
).lo))
) {
1094 /*
1095 * If the value is exactly equal to our threshold, we
1096 * want one more event in the positive direction to
1097 * ensure we pick up when the value *exceeds* this
1098 * threshold.
1099 */
1100 psci->bracket_greater = pTrigger->test_value;
1101 pnewgtval = &psci->bracket_greater;
1102 }
1103 else if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value)((pCounter->value).hi>(pTrigger->test_value).hi || (
(pCounter->value).hi==(pTrigger->test_value).hi &&
(pCounter->value).lo>(pTrigger->test_value).lo))
&&
1104 XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)((pTrigger->test_value).hi>(psci->bracket_less).hi ||
((pTrigger->test_value).hi==(psci->bracket_less).hi &&
(pTrigger->test_value).lo>(psci->bracket_less).lo))
) {
1105 psci->bracket_less = pTrigger->test_value;
1106 pnewltval = &psci->bracket_less;
1107 }
1108 }
1109 } /* end for each trigger */
1110
1111 (*psci->BracketValues) ((void *) pCounter, pnewltval, pnewgtval);
1112
1113}
1114
1115/*
1116 * ***** Resource delete functions
1117 */
1118
1119/* ARGSUSED */
1120static int
1121FreeAlarm(void *addr, XID id)
1122{
1123 SyncAlarm *pAlarm = (SyncAlarm *) addr;
1124
1125 pAlarm->state = XSyncAlarmDestroyed;
1126
1127 SyncSendAlarmNotifyEvents(pAlarm);
1128
1129 /* delete event selections */
1130
1131 while (pAlarm->pEventClients)
1132 FreeResource(pAlarm->pEventClients->delete_id, RT_NONE((RESTYPE)0));
1133
1134 SyncDeleteTriggerFromSyncObject(&pAlarm->trigger);
1135
1136 free(pAlarm);
1137 return Success0;
1138}
1139
1140/*
1141 * ** Cleanup after the destruction of a Counter
1142 */
1143/* ARGSUSED */
1144static int
1145FreeCounter(void *env, XID id)
1146{
1147 SyncCounter *pCounter = (SyncCounter *) env;
1148 SyncTriggerList *ptl, *pnext;
1149
1150 pCounter->sync.beingDestroyed = TRUE1;
1151 /* tell all the counter's triggers that the counter has been destroyed */
1152 for (ptl = pCounter->sync.pTriglist; ptl; ptl = pnext) {
1153 (*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger);
1154 pnext = ptl->next;
1155 free(ptl); /* destroy the trigger list as we go */
1156 }
1157 if (IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0))
)
) {
1158 xorg_list_del(&pCounter->pSysCounterInfo->entry);
1159 free(pCounter->pSysCounterInfo->name);
1160 free(pCounter->pSysCounterInfo->private);
1161 free(pCounter->pSysCounterInfo);
1162 }
1163 free(pCounter);
1164 return Success0;
1165}
1166
1167/*
1168 * ** Cleanup after Await
1169 */
1170/* ARGSUSED */
1171static int
1172FreeAwait(void *addr, XID id)
1173{
1174 SyncAwaitUnion *pAwaitUnion = (SyncAwaitUnion *) addr;
1175 SyncAwait *pAwait;
1176 int numwaits;
1177
1178 pAwait = &(pAwaitUnion + 1)->await; /* first await on list */
1179
1180 /* remove triggers from counters */
1181
1182 for (numwaits = pAwaitUnion->header.num_waitconditions; numwaits;
1183 numwaits--, pAwait++) {
1184 /* If the counter is being destroyed, FreeCounter will delete
1185 * the trigger list itself, so don't do it here.
1186 */
1187 SyncObject *pSync = pAwait->trigger.pSync;
1188
1189 if (pSync && !pSync->beingDestroyed)
1190 SyncDeleteTriggerFromSyncObject(&pAwait->trigger);
1191 }
1192 free(pAwaitUnion);
1193 return Success0;
1194}
1195
1196/* loosely based on dix/events.c/OtherClientGone */
1197static int
1198FreeAlarmClient(void *value, XID id)
1199{
1200 SyncAlarm *pAlarm = (SyncAlarm *) value;
1201 SyncAlarmClientList *pCur, *pPrev;
1202
1203 for (pPrev = NULL((void*)0), pCur = pAlarm->pEventClients;
1204 pCur; pPrev = pCur, pCur = pCur->next) {
1205 if (pCur->delete_id == id) {
1206 if (pPrev)
1207 pPrev->next = pCur->next;
1208 else
1209 pAlarm->pEventClients = pCur->next;
1210 free(pCur);
1211 return Success0;
1212 }
1213 }
1214 FatalError("alarm client not on event list");
1215 /*NOTREACHED*/}
1216
1217/*
1218 * ***** Proc functions
1219 */
1220
1221/*
1222 * ** Initialize the extension
1223 */
1224static int
1225ProcSyncInitialize(ClientPtr client)
1226{
1227 xSyncInitializeReply rep = {
1228 .type = X_Reply1,
1229 .sequenceNumber = client->sequence,
1230 .length = 0,
1231 .majorVersion = SERVER_SYNC_MAJOR_VERSION3,
1232 .minorVersion = SERVER_SYNC_MINOR_VERSION1,
1233 };
1234
1235 REQUEST_SIZE_MATCH(xSyncInitializeReq)if ((sizeof(xSyncInitializeReq) >> 2) != client->req_len
) return(16)
;
1236
1237 if (client->swapped) {
1238 swaps(&rep.sequenceNumber)do { if (sizeof(*(&rep.sequenceNumber)) != 2) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&rep.sequenceNumber
) & 1) && ((uintptr_t)(&rep.sequenceNumber) &
1) == 0) *(&rep.sequenceNumber) = lswaps(*(&rep.sequenceNumber
)); else swap_uint16((uint16_t *)(&rep.sequenceNumber)); }
while (0)
;
1239 }
1240 WriteToClient(client, sizeof(rep), &rep);
1241 return Success0;
1242}
1243
1244/*
1245 * ** Get list of system counters available through the extension
1246 */
1247static int
1248ProcSyncListSystemCounters(ClientPtr client)
1249{
1250 xSyncListSystemCountersReply rep = {
1251 .type = X_Reply1,
1252 .sequenceNumber = client->sequence,
1253 .nCounters = 0,
1254 };
1255 SysCounterInfo *psci;
1256 int len = 0;
1257 xSyncSystemCounter *list = NULL((void*)0), *walklist = NULL((void*)0);
1258
1259 REQUEST_SIZE_MATCH(xSyncListSystemCountersReq)if ((sizeof(xSyncListSystemCountersReq) >> 2) != client
->req_len) return(16)
;
1260
1261 xorg_list_for_each_entry(psci, &SysCounterList, entry)for (psci = ((void*)0), psci = (typeof(*psci) *)((char *)((&
SysCounterList)->next) - __builtin_offsetof(typeof(*psci),
entry)); &psci->entry != (&SysCounterList); psci =
(typeof(*psci) *)((char *)(psci->entry.next) - __builtin_offsetof
(typeof(*psci), entry)))
{
1262 /* pad to 4 byte boundary */
1263 len += pad_to_int32(sz_xSyncSystemCounter14 + strlen(psci->name));
1264 ++rep.nCounters;
1265 }
1266
1267 if (len) {
1268 walklist = list = malloc(len);
1269 if (!list)
1270 return BadAlloc11;
1271 }
1272
1273 rep.length = bytes_to_int32(len);
1274
1275 if (client->swapped) {
1276 swaps(&rep.sequenceNumber)do { if (sizeof(*(&rep.sequenceNumber)) != 2) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&rep.sequenceNumber
) & 1) && ((uintptr_t)(&rep.sequenceNumber) &
1) == 0) *(&rep.sequenceNumber) = lswaps(*(&rep.sequenceNumber
)); else swap_uint16((uint16_t *)(&rep.sequenceNumber)); }
while (0)
;
1277 swapl(&rep.length)do { if (sizeof(*(&rep.length)) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.length) & 3) && ((uintptr_t
)(&rep.length) & 3) == 0) *(&rep.length) = lswapl
(*(&rep.length)); else swap_uint32((uint32_t *)(&rep.
length)); } while (0)
;
1278 swapl(&rep.nCounters)do { if (sizeof(*(&rep.nCounters)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&rep.nCounters) & 3
) && ((uintptr_t)(&rep.nCounters) & 3) == 0) *
(&rep.nCounters) = lswapl(*(&rep.nCounters)); else swap_uint32
((uint32_t *)(&rep.nCounters)); } while (0)
;
1279 }
1280
1281 xorg_list_for_each_entry(psci, &SysCounterList, entry)for (psci = ((void*)0), psci = (typeof(*psci) *)((char *)((&
SysCounterList)->next) - __builtin_offsetof(typeof(*psci),
entry)); &psci->entry != (&SysCounterList); psci =
(typeof(*psci) *)((char *)(psci->entry.next) - __builtin_offsetof
(typeof(*psci), entry)))
{
1282 int namelen;
1283 char *pname_in_reply;
1284
1285 walklist->counter = psci->pCounter->sync.id;
1286 walklist->resolution_hi = XSyncValueHigh32(psci->resolution)((psci->resolution).hi);
1287 walklist->resolution_lo = XSyncValueLow32(psci->resolution)((psci->resolution).lo);
1288 namelen = strlen(psci->name);
1289 walklist->name_length = namelen;
1290
1291 if (client->swapped) {
1292 swapl(&walklist->counter)do { if (sizeof(*(&walklist->counter)) != 4) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&walklist->counter
) & 3) && ((uintptr_t)(&walklist->counter)
& 3) == 0) *(&walklist->counter) = lswapl(*(&
walklist->counter)); else swap_uint32((uint32_t *)(&walklist
->counter)); } while (0)
;
1293 swapl(&walklist->resolution_hi)do { if (sizeof(*(&walklist->resolution_hi)) != 4) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&walklist->resolution_hi
) & 3) && ((uintptr_t)(&walklist->resolution_hi
) & 3) == 0) *(&walklist->resolution_hi) = lswapl(
*(&walklist->resolution_hi)); else swap_uint32((uint32_t
*)(&walklist->resolution_hi)); } while (0)
;
1294 swapl(&walklist->resolution_lo)do { if (sizeof(*(&walklist->resolution_lo)) != 4) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&walklist->resolution_lo
) & 3) && ((uintptr_t)(&walklist->resolution_lo
) & 3) == 0) *(&walklist->resolution_lo) = lswapl(
*(&walklist->resolution_lo)); else swap_uint32((uint32_t
*)(&walklist->resolution_lo)); } while (0)
;
1295 swaps(&walklist->name_length)do { if (sizeof(*(&walklist->name_length)) != 2) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&walklist->name_length
) & 1) && ((uintptr_t)(&walklist->name_length
) & 1) == 0) *(&walklist->name_length) = lswaps(*(
&walklist->name_length)); else swap_uint16((uint16_t *
)(&walklist->name_length)); } while (0)
;
1296 }
1297
1298 pname_in_reply = ((char *) walklist) + sz_xSyncSystemCounter14;
1299 strncpy(pname_in_reply, psci->name, namelen)__builtin___strncpy_chk (pname_in_reply, psci->name, namelen
, __builtin_object_size (pname_in_reply, 2 > 1 ? 1 : 0))
;
1300 walklist = (xSyncSystemCounter *) (((char *) walklist) +
1301 pad_to_int32(sz_xSyncSystemCounter14 +
1302 namelen));
1303 }
1304
1305 WriteToClient(client, sizeof(rep), &rep);
1306 if (len) {
1307 WriteToClient(client, len, list);
1308 free(list);
1309 }
1310
1311 return Success0;
1312}
1313
1314/*
1315 * ** Set client Priority
1316 */
1317static int
1318ProcSyncSetPriority(ClientPtr client)
1319{
1320 REQUEST(xSyncSetPriorityReq)xSyncSetPriorityReq *stuff = (xSyncSetPriorityReq *)client->
requestBuffer
;
1321 ClientPtr priorityclient;
1322 int rc;
1323
1324 REQUEST_SIZE_MATCH(xSyncSetPriorityReq)if ((sizeof(xSyncSetPriorityReq) >> 2) != client->req_len
) return(16)
;
1325
1326 if (stuff->id == None0L)
1327 priorityclient = client;
1328 else {
1329 rc = dixLookupClient(&priorityclient, stuff->id, client,
1330 DixSetAttrAccess(1<<5));
1331 if (rc != Success0)
1332 return rc;
1333 }
1334
1335 if (priorityclient->priority != stuff->priority) {
1336 priorityclient->priority = stuff->priority;
1337
1338 /* The following will force the server back into WaitForSomething
1339 * so that the change in this client's priority is immediately
1340 * reflected.
1341 */
1342 isItTimeToYield = TRUE1;
1343 dispatchException |= DE_PRIORITYCHANGE4;
1344 }
1345 return Success0;
1346}
1347
1348/*
1349 * ** Get client Priority
1350 */
1351static int
1352ProcSyncGetPriority(ClientPtr client)
1353{
1354 REQUEST(xSyncGetPriorityReq)xSyncGetPriorityReq *stuff = (xSyncGetPriorityReq *)client->
requestBuffer
;
1355 xSyncGetPriorityReply rep;
1356 ClientPtr priorityclient;
1357 int rc;
1358
1359 REQUEST_SIZE_MATCH(xSyncGetPriorityReq)if ((sizeof(xSyncGetPriorityReq) >> 2) != client->req_len
) return(16)
;
1360
1361 if (stuff->id == None0L)
1362 priorityclient = client;
1363 else {
1364 rc = dixLookupClient(&priorityclient, stuff->id, client,
1365 DixGetAttrAccess(1<<4));
1366 if (rc != Success0)
1367 return rc;
1368 }
1369
1370 rep = (xSyncGetPriorityReply) {
1371 .type = X_Reply1,
1372 .sequenceNumber = client->sequence,
1373 .length = 0,
1374 .priority = priorityclient->priority
1375 };
1376
1377 if (client->swapped) {
1378 swaps(&rep.sequenceNumber)do { if (sizeof(*(&rep.sequenceNumber)) != 2) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&rep.sequenceNumber
) & 1) && ((uintptr_t)(&rep.sequenceNumber) &
1) == 0) *(&rep.sequenceNumber) = lswaps(*(&rep.sequenceNumber
)); else swap_uint16((uint16_t *)(&rep.sequenceNumber)); }
while (0)
;
1379 swapl(&rep.priority)do { if (sizeof(*(&rep.priority)) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&rep.priority) & 3) &&
((uintptr_t)(&rep.priority) & 3) == 0) *(&rep.priority
) = lswapl(*(&rep.priority)); else swap_uint32((uint32_t *
)(&rep.priority)); } while (0)
;
1380 }
1381
1382 WriteToClient(client, sizeof(xSyncGetPriorityReply), &rep);
1383
1384 return Success0;
1385}
1386
1387/*
1388 * ** Create a new counter
1389 */
1390static int
1391ProcSyncCreateCounter(ClientPtr client)
1392{
1393 REQUEST(xSyncCreateCounterReq)xSyncCreateCounterReq *stuff = (xSyncCreateCounterReq *)client
->requestBuffer
;
1394 CARD64XSyncValue initial;
1395
1396 REQUEST_SIZE_MATCH(xSyncCreateCounterReq)if ((sizeof(xSyncCreateCounterReq) >> 2) != client->
req_len) return(16)
;
1397
1398 LEGAL_NEW_RESOURCE(stuff->cid, client)if (!LegalNewID(stuff->cid,client)) { client->errorValue
= stuff->cid; return 14; }
;
1399
1400 XSyncIntsToValue(&initial, stuff->initial_value_lo,((&initial)->lo = (stuff->initial_value_lo), (&
initial)->hi = (stuff->initial_value_hi))
1401 stuff->initial_value_hi)((&initial)->lo = (stuff->initial_value_lo), (&
initial)->hi = (stuff->initial_value_hi))
;
1402 if (!SyncCreateCounter(client, stuff->cid, initial))
1403 return BadAlloc11;
1404
1405 return Success0;
1406}
1407
1408/*
1409 * ** Set Counter value
1410 */
1411static int
1412ProcSyncSetCounter(ClientPtr client)
1413{
1414 REQUEST(xSyncSetCounterReq)xSyncSetCounterReq *stuff = (xSyncSetCounterReq *)client->
requestBuffer
;
1415 SyncCounter *pCounter;
1416 CARD64XSyncValue newvalue;
1417 int rc;
1418
1419 REQUEST_SIZE_MATCH(xSyncSetCounterReq)if ((sizeof(xSyncSetCounterReq) >> 2) != client->req_len
) return(16)
;
1420
1421 rc = dixLookupResourceByType((void **) &pCounter, stuff->cid, RTCounter,
1422 client, DixWriteAccess(1<<1));
1423 if (rc != Success0)
1424 return rc;
1425
1426 if (IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0))
)
) {
1427 client->errorValue = stuff->cid;
1428 return BadAccess10;
1429 }
1430
1431 XSyncIntsToValue(&newvalue, stuff->value_lo, stuff->value_hi)((&newvalue)->lo = (stuff->value_lo), (&newvalue
)->hi = (stuff->value_hi))
;
1432 SyncChangeCounter(pCounter, newvalue);
1433 return Success0;
1434}
1435
1436/*
1437 * ** Change Counter value
1438 */
1439static int
1440ProcSyncChangeCounter(ClientPtr client)
1441{
1442 REQUEST(xSyncChangeCounterReq)xSyncChangeCounterReq *stuff = (xSyncChangeCounterReq *)client
->requestBuffer
;
1443 SyncCounter *pCounter;
1444 CARD64XSyncValue newvalue;
1445 Bool overflow;
1446 int rc;
1447
1448 REQUEST_SIZE_MATCH(xSyncChangeCounterReq)if ((sizeof(xSyncChangeCounterReq) >> 2) != client->
req_len) return(16)
;
1449
1450 rc = dixLookupResourceByType((void **) &pCounter, stuff->cid, RTCounter,
1451 client, DixWriteAccess(1<<1));
1452 if (rc != Success0)
1453 return rc;
1454
1455 if (IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0))
)
) {
1456 client->errorValue = stuff->cid;
1457 return BadAccess10;
1458 }
1459
1460 XSyncIntsToValue(&newvalue, stuff->value_lo, stuff->value_hi)((&newvalue)->lo = (stuff->value_lo), (&newvalue
)->hi = (stuff->value_hi))
;
1461 XSyncValueAdd(&newvalue, pCounter->value, newvalue, &overflow){ int t = (pCounter->value).lo; Bool signa = (((pCounter->
value).hi & 0x80000000) ? 1 : 0); Bool signb = (((newvalue
).hi & 0x80000000) ? 1 : 0); ((&newvalue)->lo = (pCounter
->value).lo + (newvalue).lo); ((&newvalue)->hi = (pCounter
->value).hi + (newvalue).hi); if (t>(&newvalue)->
lo) (&newvalue)->hi++; *&overflow = ((signa == signb
) && !(signa == (((*&newvalue).hi & 0x80000000
) ? 1 : 0))); }
;
1462 if (overflow) {
1463 /* XXX 64 bit value can't fit in 32 bits; do the best we can */
1464 client->errorValue = stuff->value_hi;
1465 return BadValue2;
1466 }
1467 SyncChangeCounter(pCounter, newvalue);
1468 return Success0;
1469}
1470
1471/*
1472 * ** Destroy a counter
1473 */
1474static int
1475ProcSyncDestroyCounter(ClientPtr client)
1476{
1477 REQUEST(xSyncDestroyCounterReq)xSyncDestroyCounterReq *stuff = (xSyncDestroyCounterReq *)client
->requestBuffer
;
1478 SyncCounter *pCounter;
1479 int rc;
1480
1481 REQUEST_SIZE_MATCH(xSyncDestroyCounterReq)if ((sizeof(xSyncDestroyCounterReq) >> 2) != client->
req_len) return(16)
;
1482
1483 rc = dixLookupResourceByType((void **) &pCounter, stuff->counter,
1484 RTCounter, client, DixDestroyAccess(1<<2));
1485 if (rc != Success0)
1486 return rc;
1487
1488 if (IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0))
)
) {
1489 client->errorValue = stuff->counter;
1490 return BadAccess10;
1491 }
1492 FreeResource(pCounter->sync.id, RT_NONE((RESTYPE)0));
1493 return Success0;
1494}
1495
1496static SyncAwaitUnion *
1497SyncAwaitPrologue(ClientPtr client, int items)
1498{
1499 SyncAwaitUnion *pAwaitUnion;
1500
1501 /* all the memory for the entire await list is allocated
1502 * here in one chunk
1503 */
1504 pAwaitUnion = xallocarray(items + 1, sizeof(SyncAwaitUnion))xreallocarray(((void*)0), (items + 1), (sizeof(SyncAwaitUnion
)))
;
1505 if (!pAwaitUnion)
1506 return NULL((void*)0);
1507
1508 /* first item is the header, remainder are real wait conditions */
1509
1510 pAwaitUnion->header.delete_id = FakeClientID(client->index);
1511 pAwaitUnion->header.client = client;
1512 pAwaitUnion->header.num_waitconditions = 0;
1513
1514 if (!AddResourceDarwin_X_AddResource(pAwaitUnion->header.delete_id, RTAwait, pAwaitUnion))
1515 return NULL((void*)0);
1516
1517 return pAwaitUnion;
1518}
1519
1520static void
1521SyncAwaitEpilogue(ClientPtr client, int items, SyncAwaitUnion * pAwaitUnion)
1522{
1523 SyncAwait *pAwait;
1524 int i;
1525
1526 IgnoreClient(client);
1527
1528 /* see if any of the triggers are already true */
1529
1530 pAwait = &(pAwaitUnion + 1)->await; /* skip over header */
1531 for (i = 0; i < items; i++, pAwait++) {
1532 CARD64XSyncValue value;
1533
1534 /* don't have to worry about NULL counters because the request
1535 * errors before we get here out if they occur
1536 */
1537 switch (pAwait->trigger.pSync->type) {
1538 case SYNC_COUNTER0:
1539 value = ((SyncCounter *) pAwait->trigger.pSync)->value;
1540 break;
1541 default:
1542 XSyncIntToValue(&value, 0)((&value)->hi=((0<0)?~0:0),(&value)->lo=(0));
1543 }
1544
1545 if ((*pAwait->trigger.CheckTrigger) (&pAwait->trigger, value)) {
1546 (*pAwait->trigger.TriggerFired) (&pAwait->trigger);
1547 break; /* once is enough */
1548 }
1549 }
1550}
1551
1552/*
1553 * ** Await
1554 */
1555static int
1556ProcSyncAwait(ClientPtr client)
1557{
1558 REQUEST(xSyncAwaitReq)xSyncAwaitReq *stuff = (xSyncAwaitReq *)client->requestBuffer;
1559 int len, items;
1560 int i;
1561 xSyncWaitCondition *pProtocolWaitConds;
1562 SyncAwaitUnion *pAwaitUnion;
1563 SyncAwait *pAwait;
1564 int status;
1565
1566 REQUEST_AT_LEAST_SIZE(xSyncAwaitReq)if ((sizeof(xSyncAwaitReq) >> 2) > client->req_len
) return(16)
;
1567
1568 len = client->req_len << 2;
1569 len -= sz_xSyncAwaitReq4;
1570 items = len / sz_xSyncWaitCondition28;
1571
1572 if (items * sz_xSyncWaitCondition28 != len) {
1573 return BadLength16;
1574 }
1575 if (items == 0) {
1576 client->errorValue = items; /* XXX protocol change */
1577 return BadValue2;
1578 }
1579
1580 if (!(pAwaitUnion = SyncAwaitPrologue(client, items)))
1581 return BadAlloc11;
1582
1583 /* don't need to do any more memory allocation for this request! */
1584
1585 pProtocolWaitConds = (xSyncWaitCondition *) &stuff[1];
1586
1587 pAwait = &(pAwaitUnion + 1)->await; /* skip over header */
1588 for (i = 0; i < items; i++, pProtocolWaitConds++, pAwait++) {
1589 if (pProtocolWaitConds->counter == None0L) { /* XXX protocol change */
1590 /* this should take care of removing any triggers created by
1591 * this request that have already been registered on sync objects
1592 */
1593 FreeResource(pAwaitUnion->header.delete_id, RT_NONE((RESTYPE)0));
1594 client->errorValue = pProtocolWaitConds->counter;
1595 return SyncErrorBase + XSyncBadCounter0L;
1596 }
1597
1598 /* sanity checks are in SyncInitTrigger */
1599 pAwait->trigger.pSync = NULL((void*)0);
1600 pAwait->trigger.value_type = pProtocolWaitConds->value_type;
1601 XSyncIntsToValue(&pAwait->trigger.wait_value,((&pAwait->trigger.wait_value)->lo = (pProtocolWaitConds
->wait_value_lo), (&pAwait->trigger.wait_value)->
hi = (pProtocolWaitConds->wait_value_hi))
1602 pProtocolWaitConds->wait_value_lo,((&pAwait->trigger.wait_value)->lo = (pProtocolWaitConds
->wait_value_lo), (&pAwait->trigger.wait_value)->
hi = (pProtocolWaitConds->wait_value_hi))
1603 pProtocolWaitConds->wait_value_hi)((&pAwait->trigger.wait_value)->lo = (pProtocolWaitConds
->wait_value_lo), (&pAwait->trigger.wait_value)->
hi = (pProtocolWaitConds->wait_value_hi))
;
1604 pAwait->trigger.test_type = pProtocolWaitConds->test_type;
1605
1606 status = SyncInitTrigger(client, &pAwait->trigger,
1607 pProtocolWaitConds->counter, RTCounter,
1608 XSyncCAAllTrigger((1L<<0) | (1L<<1) | (1L<<2) | (1L<<3
))
);
1609 if (status != Success0) {
1610 /* this should take care of removing any triggers created by
1611 * this request that have already been registered on sync objects
1612 */
1613 FreeResource(pAwaitUnion->header.delete_id, RT_NONE((RESTYPE)0));
1614 return status;
1615 }
1616 /* this is not a mistake -- same function works for both cases */
1617 pAwait->trigger.TriggerFired = SyncAwaitTriggerFired;
1618 pAwait->trigger.CounterDestroyed = SyncAwaitTriggerFired;
1619 XSyncIntsToValue(&pAwait->event_threshold,((&pAwait->event_threshold)->lo = (pProtocolWaitConds
->event_threshold_lo), (&pAwait->event_threshold)->
hi = (pProtocolWaitConds->event_threshold_hi))
1620 pProtocolWaitConds->event_threshold_lo,((&pAwait->event_threshold)->lo = (pProtocolWaitConds
->event_threshold_lo), (&pAwait->event_threshold)->
hi = (pProtocolWaitConds->event_threshold_hi))
1621 pProtocolWaitConds->event_threshold_hi)((&pAwait->event_threshold)->lo = (pProtocolWaitConds
->event_threshold_lo), (&pAwait->event_threshold)->
hi = (pProtocolWaitConds->event_threshold_hi))
;
1622 pAwait->pHeader = &pAwaitUnion->header;
1623 pAwaitUnion->header.num_waitconditions++;
1624 }
1625
1626 SyncAwaitEpilogue(client, items, pAwaitUnion);
1627
1628 return Success0;
1629}
1630
1631/*
1632 * ** Query a counter
1633 */
1634static int
1635ProcSyncQueryCounter(ClientPtr client)
1636{
1637 REQUEST(xSyncQueryCounterReq)xSyncQueryCounterReq *stuff = (xSyncQueryCounterReq *)client->
requestBuffer
;
1638 xSyncQueryCounterReply rep;
1639 SyncCounter *pCounter;
1640 int rc;
1641
1642 REQUEST_SIZE_MATCH(xSyncQueryCounterReq)if ((sizeof(xSyncQueryCounterReq) >> 2) != client->req_len
) return(16)
;
1643
1644 rc = dixLookupResourceByType((void **) &pCounter, stuff->counter,
1645 RTCounter, client, DixReadAccess(1<<0));
1646 if (rc != Success0)
1647 return rc;
1648
1649 /* if system counter, ask it what the current value is */
1650 if (IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0))
)
) {
1651 (*pCounter->pSysCounterInfo->QueryValue) ((void *) pCounter,
1652 &pCounter->value);
1653 }
1654
1655 rep = (xSyncQueryCounterReply) {
1656 .type = X_Reply1,
1657 .sequenceNumber = client->sequence,
1658 .length = 0,
1659 .value_hi = XSyncValueHigh32(pCounter->value)((pCounter->value).hi),
1660 .value_lo = XSyncValueLow32(pCounter->value)((pCounter->value).lo)
1661 };
1662
1663 if (client->swapped) {
1664 swaps(&rep.sequenceNumber)do { if (sizeof(*(&rep.sequenceNumber)) != 2) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&rep.sequenceNumber
) & 1) && ((uintptr_t)(&rep.sequenceNumber) &
1) == 0) *(&rep.sequenceNumber) = lswaps(*(&rep.sequenceNumber
)); else swap_uint16((uint16_t *)(&rep.sequenceNumber)); }
while (0)
;
1665 swapl(&rep.length)do { if (sizeof(*(&rep.length)) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.length) & 3) && ((uintptr_t
)(&rep.length) & 3) == 0) *(&rep.length) = lswapl
(*(&rep.length)); else swap_uint32((uint32_t *)(&rep.
length)); } while (0)
;
1666 swapl(&rep.value_hi)do { if (sizeof(*(&rep.value_hi)) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&rep.value_hi) & 3) &&
((uintptr_t)(&rep.value_hi) & 3) == 0) *(&rep.value_hi
) = lswapl(*(&rep.value_hi)); else swap_uint32((uint32_t *
)(&rep.value_hi)); } while (0)
;
1667 swapl(&rep.value_lo)do { if (sizeof(*(&rep.value_lo)) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&rep.value_lo) & 3) &&
((uintptr_t)(&rep.value_lo) & 3) == 0) *(&rep.value_lo
) = lswapl(*(&rep.value_lo)); else swap_uint32((uint32_t *
)(&rep.value_lo)); } while (0)
;
1668 }
1669 WriteToClient(client, sizeof(xSyncQueryCounterReply), &rep);
1670 return Success0;
1671}
1672
1673/*
1674 * ** Create Alarm
1675 */
1676static int
1677ProcSyncCreateAlarm(ClientPtr client)
1678{
1679 REQUEST(xSyncCreateAlarmReq)xSyncCreateAlarmReq *stuff = (xSyncCreateAlarmReq *)client->
requestBuffer
;
1680 SyncAlarm *pAlarm;
1681 int status;
1682 unsigned long len, vmask;
1683 SyncTrigger *pTrigger;
1684
1685 REQUEST_AT_LEAST_SIZE(xSyncCreateAlarmReq)if ((sizeof(xSyncCreateAlarmReq) >> 2) > client->
req_len ) return(16)
;
1686
1687 LEGAL_NEW_RESOURCE(stuff->id, client)if (!LegalNewID(stuff->id,client)) { client->errorValue
= stuff->id; return 14; }
;
1688
1689 vmask = stuff->valueMask;
1690 len = client->req_len - bytes_to_int32(sizeof(xSyncCreateAlarmReq));
1691 /* the "extra" call to Ones accounts for the presence of 64 bit values */
1692 if (len != (Ones(vmask) + Ones(vmask & (XSyncCAValue(1L<<2) | XSyncCADelta(1L<<4)))))
1693 return BadLength16;
1694
1695 if (!(pAlarm = malloc(sizeof(SyncAlarm)))) {
1696 return BadAlloc11;
1697 }
1698
1699 /* set up defaults */
1700
1701 pTrigger = &pAlarm->trigger;
1702 pTrigger->pSync = NULL((void*)0);
1703 pTrigger->value_type = XSyncAbsolute;
1704 XSyncIntToValue(&pTrigger->wait_value, 0L)((&pTrigger->wait_value)->hi=((0L<0)?~0:0),(&
pTrigger->wait_value)->lo=(0L))
;
1705 pTrigger->test_type = XSyncPositiveComparison;
1706 pTrigger->TriggerFired = SyncAlarmTriggerFired;
1707 pTrigger->CounterDestroyed = SyncAlarmCounterDestroyed;
1708 status = SyncInitTrigger(client, pTrigger, None0L, RTCounter,
1709 XSyncCAAllTrigger((1L<<0) | (1L<<1) | (1L<<2) | (1L<<3
))
);
1710 if (status != Success0) {
1711 free(pAlarm);
1712 return status;
1713 }
1714
1715 pAlarm->client = client;
1716 pAlarm->alarm_id = stuff->id;
1717 XSyncIntToValue(&pAlarm->delta, 1L)((&pAlarm->delta)->hi=((1L<0)?~0:0),(&pAlarm
->delta)->lo=(1L))
;
1718 pAlarm->events = TRUE1;
1719 pAlarm->state = XSyncAlarmInactive;
1720 pAlarm->pEventClients = NULL((void*)0);
1721 status = SyncChangeAlarmAttributes(client, pAlarm, vmask,
1722 (CARD32 *) &stuff[1]);
1723 if (status != Success0) {
1724 free(pAlarm);
1725 return status;
1726 }
1727
1728 if (!AddResourceDarwin_X_AddResource(stuff->id, RTAlarm, pAlarm))
1729 return BadAlloc11;
1730
1731 /* see if alarm already triggered. NULL counter will not trigger
1732 * in CreateAlarm and sets alarm state to Inactive.
1733 */
1734
1735 if (!pTrigger->pSync) {
1736 pAlarm->state = XSyncAlarmInactive; /* XXX protocol change */
1737 }
1738 else {
1739 SyncCounter *pCounter;
1740
1741 if (!SyncCheckWarnIsCounter(pTrigger->pSync,
1742 WARN_INVALID_COUNTER_ALARM)) {
1743 FreeResource(stuff->id, RT_NONE((RESTYPE)0));
1744 return BadAlloc11;
1745 }
1746
1747 pCounter = (SyncCounter *) pTrigger->pSync;
1748
1749 if ((*pTrigger->CheckTrigger) (pTrigger, pCounter->value))
1750 (*pTrigger->TriggerFired) (pTrigger);
1751 }
1752
1753 return Success0;
1754}
1755
1756/*
1757 * ** Change Alarm
1758 */
1759static int
1760ProcSyncChangeAlarm(ClientPtr client)
1761{
1762 REQUEST(xSyncChangeAlarmReq)xSyncChangeAlarmReq *stuff = (xSyncChangeAlarmReq *)client->
requestBuffer
;
1763 SyncAlarm *pAlarm;
1764 SyncCounter *pCounter = NULL((void*)0);
1765 long vmask;
1766 int len, status;
1767
1768 REQUEST_AT_LEAST_SIZE(xSyncChangeAlarmReq)if ((sizeof(xSyncChangeAlarmReq) >> 2) > client->
req_len ) return(16)
;
1769
1770 status = dixLookupResourceByType((void **) &pAlarm, stuff->alarm, RTAlarm,
1771 client, DixWriteAccess(1<<1));
1772 if (status != Success0)
1773 return status;
1774
1775 vmask = stuff->valueMask;
1776 len = client->req_len - bytes_to_int32(sizeof(xSyncChangeAlarmReq));
1777 /* the "extra" call to Ones accounts for the presence of 64 bit values */
1778 if (len != (Ones(vmask) + Ones(vmask & (XSyncCAValue(1L<<2) | XSyncCADelta(1L<<4)))))
1779 return BadLength16;
1780
1781 if ((status = SyncChangeAlarmAttributes(client, pAlarm, vmask,
1782 (CARD32 *) &stuff[1])) != Success0)
1783 return status;
1784
1785 if (SyncCheckWarnIsCounter(pAlarm->trigger.pSync,
1786 WARN_INVALID_COUNTER_ALARM))
1787 pCounter = (SyncCounter *) pAlarm->trigger.pSync;
1788
1789 /* see if alarm already triggered. NULL counter WILL trigger
1790 * in ChangeAlarm.
1791 */
1792
1793 if (!pCounter ||
1794 (*pAlarm->trigger.CheckTrigger) (&pAlarm->trigger, pCounter->value)) {
1795 (*pAlarm->trigger.TriggerFired) (&pAlarm->trigger);
1796 }
1797 return Success0;
1798}
1799
1800static int
1801ProcSyncQueryAlarm(ClientPtr client)
1802{
1803 REQUEST(xSyncQueryAlarmReq)xSyncQueryAlarmReq *stuff = (xSyncQueryAlarmReq *)client->
requestBuffer
;
1804 SyncAlarm *pAlarm;
1805 xSyncQueryAlarmReply rep;
1806 SyncTrigger *pTrigger;
1807 int rc;
1808
1809 REQUEST_SIZE_MATCH(xSyncQueryAlarmReq)if ((sizeof(xSyncQueryAlarmReq) >> 2) != client->req_len
) return(16)
;
1810
1811 rc = dixLookupResourceByType((void **) &pAlarm, stuff->alarm, RTAlarm,
1812 client, DixReadAccess(1<<0));
1813 if (rc != Success0)
1814 return rc;
1815
1816 pTrigger = &pAlarm->trigger;
1817 rep = (xSyncQueryAlarmReply) {
1818 .type = X_Reply1,
1819 .sequenceNumber = client->sequence,
1820 .length =
1821 bytes_to_int32(sizeof(xSyncQueryAlarmReply) - sizeof(xGenericReply)),
1822 .counter = (pTrigger->pSync) ? pTrigger->pSync->id : None0L,
1823
1824#if 0 /* XXX unclear what to do, depends on whether relative value-types
1825 * are "consumed" immediately and are considered absolute from then
1826 * on.
1827 */
1828 .value_type = pTrigger->value_type,
1829 .wait_value_hi = XSyncValueHigh32(pTrigger->wait_value)((pTrigger->wait_value).hi),
1830 .wait_value_lo = XSyncValueLow32(pTrigger->wait_value)((pTrigger->wait_value).lo),
1831#else
1832 .value_type = XSyncAbsolute,
1833 .wait_value_hi = XSyncValueHigh32(pTrigger->test_value)((pTrigger->test_value).hi),
1834 .wait_value_lo = XSyncValueLow32(pTrigger->test_value)((pTrigger->test_value).lo),
1835#endif
1836
1837 .test_type = pTrigger->test_type,
1838 .delta_hi = XSyncValueHigh32(pAlarm->delta)((pAlarm->delta).hi),
1839 .delta_lo = XSyncValueLow32(pAlarm->delta)((pAlarm->delta).lo),
1840 .events = pAlarm->events,
1841 .state = pAlarm->state
1842 };
1843
1844 if (client->swapped) {
1845 swaps(&rep.sequenceNumber)do { if (sizeof(*(&rep.sequenceNumber)) != 2) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&rep.sequenceNumber
) & 1) && ((uintptr_t)(&rep.sequenceNumber) &
1) == 0) *(&rep.sequenceNumber) = lswaps(*(&rep.sequenceNumber
)); else swap_uint16((uint16_t *)(&rep.sequenceNumber)); }
while (0)
;
1846 swapl(&rep.length)do { if (sizeof(*(&rep.length)) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.length) & 3) && ((uintptr_t
)(&rep.length) & 3) == 0) *(&rep.length) = lswapl
(*(&rep.length)); else swap_uint32((uint32_t *)(&rep.
length)); } while (0)
;
1847 swapl(&rep.counter)do { if (sizeof(*(&rep.counter)) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&rep.counter) & 3) &&
((uintptr_t)(&rep.counter) & 3) == 0) *(&rep.counter
) = lswapl(*(&rep.counter)); else swap_uint32((uint32_t *
)(&rep.counter)); } while (0)
;
1848 swapl(&rep.wait_value_hi)do { if (sizeof(*(&rep.wait_value_hi)) != 4) wrong_size()
; if (__builtin_constant_p((uintptr_t)(&rep.wait_value_hi
) & 3) && ((uintptr_t)(&rep.wait_value_hi) &
3) == 0) *(&rep.wait_value_hi) = lswapl(*(&rep.wait_value_hi
)); else swap_uint32((uint32_t *)(&rep.wait_value_hi)); }
while (0)
;
1849 swapl(&rep.wait_value_lo)do { if (sizeof(*(&rep.wait_value_lo)) != 4) wrong_size()
; if (__builtin_constant_p((uintptr_t)(&rep.wait_value_lo
) & 3) && ((uintptr_t)(&rep.wait_value_lo) &
3) == 0) *(&rep.wait_value_lo) = lswapl(*(&rep.wait_value_lo
)); else swap_uint32((uint32_t *)(&rep.wait_value_lo)); }
while (0)
;
1850 swapl(&rep.test_type)do { if (sizeof(*(&rep.test_type)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&rep.test_type) & 3
) && ((uintptr_t)(&rep.test_type) & 3) == 0) *
(&rep.test_type) = lswapl(*(&rep.test_type)); else swap_uint32
((uint32_t *)(&rep.test_type)); } while (0)
;
1851 swapl(&rep.delta_hi)do { if (sizeof(*(&rep.delta_hi)) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&rep.delta_hi) & 3) &&
((uintptr_t)(&rep.delta_hi) & 3) == 0) *(&rep.delta_hi
) = lswapl(*(&rep.delta_hi)); else swap_uint32((uint32_t *
)(&rep.delta_hi)); } while (0)
;
1852 swapl(&rep.delta_lo)do { if (sizeof(*(&rep.delta_lo)) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&rep.delta_lo) & 3) &&
((uintptr_t)(&rep.delta_lo) & 3) == 0) *(&rep.delta_lo
) = lswapl(*(&rep.delta_lo)); else swap_uint32((uint32_t *
)(&rep.delta_lo)); } while (0)
;
1853 }
1854
1855 WriteToClient(client, sizeof(xSyncQueryAlarmReply), &rep);
1856 return Success0;
1857}
1858
1859static int
1860ProcSyncDestroyAlarm(ClientPtr client)
1861{
1862 SyncAlarm *pAlarm;
1863 int rc;
1864
1865 REQUEST(xSyncDestroyAlarmReq)xSyncDestroyAlarmReq *stuff = (xSyncDestroyAlarmReq *)client->
requestBuffer
;
1866
1867 REQUEST_SIZE_MATCH(xSyncDestroyAlarmReq)if ((sizeof(xSyncDestroyAlarmReq) >> 2) != client->req_len
) return(16)
;
1868
1869 rc = dixLookupResourceByType((void **) &pAlarm, stuff->alarm, RTAlarm,
1870 client, DixDestroyAccess(1<<2));
1871 if (rc != Success0)
1872 return rc;
1873
1874 FreeResource(stuff->alarm, RT_NONE((RESTYPE)0));
1875 return Success0;
1876}
1877
1878static int
1879ProcSyncCreateFence(ClientPtr client)
1880{
1881 REQUEST(xSyncCreateFenceReq)xSyncCreateFenceReq *stuff = (xSyncCreateFenceReq *)client->
requestBuffer
;
1882 DrawablePtr pDraw;
1883 SyncFence *pFence;
1884 int rc;
1885
1886 REQUEST_SIZE_MATCH(xSyncCreateFenceReq)if ((sizeof(xSyncCreateFenceReq) >> 2) != client->req_len
) return(16)
;
1887
1888 rc = dixLookupDrawable(&pDraw, stuff->d, client, M_ANY(-1), DixGetAttrAccess(1<<4));
1889 if (rc != Success0)
1890 return rc;
1891
1892 LEGAL_NEW_RESOURCE(stuff->fid, client)if (!LegalNewID(stuff->fid,client)) { client->errorValue
= stuff->fid; return 14; }
;
1893
1894 if (!(pFence = (SyncFence *) SyncCreate(client, stuff->fid, SYNC_FENCE1)))
1895 return BadAlloc11;
1896
1897 miSyncInitFence(pDraw->pScreen, pFence, stuff->initially_triggered);
1898
1899 if (!AddResourceDarwin_X_AddResource(stuff->fid, RTFence, (void *) pFence))
1900 return BadAlloc11;
1901
1902 return client->noClientException;
1903}
1904
1905static int
1906FreeFence(void *obj, XID id)
1907{
1908 SyncFence *pFence = (SyncFence *) obj;
1909
1910 miSyncDestroyFence(pFence);
1911
1912 return Success0;
1913}
1914
1915int
1916SyncVerifyFence(SyncFence ** ppSyncFence, XID fid, ClientPtr client, Mask mode)
1917{
1918 int rc = dixLookupResourceByType((void **) ppSyncFence, fid, RTFence,
1919 client, mode);
1920
1921 if (rc != Success0)
1922 client->errorValue = fid;
1923
1924 return rc;
1925}
1926
1927static int
1928ProcSyncTriggerFence(ClientPtr client)
1929{
1930 REQUEST(xSyncTriggerFenceReq)xSyncTriggerFenceReq *stuff = (xSyncTriggerFenceReq *)client->
requestBuffer
;
1931 SyncFence *pFence;
1932 int rc;
1933
1934 REQUEST_SIZE_MATCH(xSyncTriggerFenceReq)if ((sizeof(xSyncTriggerFenceReq) >> 2) != client->req_len
) return(16)
;
1935
1936 rc = dixLookupResourceByType((void **) &pFence, stuff->fid, RTFence,
1937 client, DixWriteAccess(1<<1));
1938 if (rc != Success0)
1939 return rc;
1940
1941 miSyncTriggerFence(pFence);
1942
1943 return client->noClientException;
1944}
1945
1946static int
1947ProcSyncResetFence(ClientPtr client)
1948{
1949 REQUEST(xSyncResetFenceReq)xSyncResetFenceReq *stuff = (xSyncResetFenceReq *)client->
requestBuffer
;
1950 SyncFence *pFence;
1951 int rc;
1952
1953 REQUEST_SIZE_MATCH(xSyncResetFenceReq)if ((sizeof(xSyncResetFenceReq) >> 2) != client->req_len
) return(16)
;
1954
1955 rc = dixLookupResourceByType((void **) &pFence, stuff->fid, RTFence,
1956 client, DixWriteAccess(1<<1));
1957 if (rc != Success0)
1958 return rc;
1959
1960 if (pFence->funcs.CheckTriggered(pFence) != TRUE1)
1961 return BadMatch8;
1962
1963 pFence->funcs.Reset(pFence);
1964
1965 return client->noClientException;
1966}
1967
1968static int
1969ProcSyncDestroyFence(ClientPtr client)
1970{
1971 REQUEST(xSyncDestroyFenceReq)xSyncDestroyFenceReq *stuff = (xSyncDestroyFenceReq *)client->
requestBuffer
;
1972 SyncFence *pFence;
1973 int rc;
1974
1975 REQUEST_SIZE_MATCH(xSyncDestroyFenceReq)if ((sizeof(xSyncDestroyFenceReq) >> 2) != client->req_len
) return(16)
;
1976
1977 rc = dixLookupResourceByType((void **) &pFence, stuff->fid, RTFence,
1978 client, DixDestroyAccess(1<<2));
1979 if (rc != Success0)
1980 return rc;
1981
1982 FreeResource(stuff->fid, RT_NONE((RESTYPE)0));
1983 return client->noClientException;
1984}
1985
1986static int
1987ProcSyncQueryFence(ClientPtr client)
1988{
1989 REQUEST(xSyncQueryFenceReq)xSyncQueryFenceReq *stuff = (xSyncQueryFenceReq *)client->
requestBuffer
;
1990 xSyncQueryFenceReply rep;
1991 SyncFence *pFence;
1992 int rc;
1993
1994 REQUEST_SIZE_MATCH(xSyncQueryFenceReq)if ((sizeof(xSyncQueryFenceReq) >> 2) != client->req_len
) return(16)
;
1995
1996 rc = dixLookupResourceByType((void **) &pFence, stuff->fid,
1997 RTFence, client, DixReadAccess(1<<0));
1998 if (rc != Success0)
1999 return rc;
2000
2001 rep = (xSyncQueryFenceReply) {
2002 .type = X_Reply1,
2003 .sequenceNumber = client->sequence,
2004 .length = 0,
2005
2006 .triggered = pFence->funcs.CheckTriggered(pFence)
2007 };
2008
2009 if (client->swapped) {
2010 swaps(&rep.sequenceNumber)do { if (sizeof(*(&rep.sequenceNumber)) != 2) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&rep.sequenceNumber
) & 1) && ((uintptr_t)(&rep.sequenceNumber) &
1) == 0) *(&rep.sequenceNumber) = lswaps(*(&rep.sequenceNumber
)); else swap_uint16((uint16_t *)(&rep.sequenceNumber)); }
while (0)
;
2011 swapl(&rep.length)do { if (sizeof(*(&rep.length)) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.length) & 3) && ((uintptr_t
)(&rep.length) & 3) == 0) *(&rep.length) = lswapl
(*(&rep.length)); else swap_uint32((uint32_t *)(&rep.
length)); } while (0)
;
2012 }
2013
2014 WriteToClient(client, sizeof(xSyncQueryFenceReply), &rep);
2015 return client->noClientException;
2016}
2017
2018static int
2019ProcSyncAwaitFence(ClientPtr client)
2020{
2021 REQUEST(xSyncAwaitFenceReq)xSyncAwaitFenceReq *stuff = (xSyncAwaitFenceReq *)client->
requestBuffer
;
2022 SyncAwaitUnion *pAwaitUnion;
2023 SyncAwait *pAwait;
2024
2025 /* Use CARD32 rather than XSyncFence because XIDs are hard-coded to
2026 * CARD32 in protocol definitions */
2027 CARD32 *pProtocolFences;
2028 int status;
2029 int len;
2030 int items;
2031 int i;
2032
2033 REQUEST_AT_LEAST_SIZE(xSyncAwaitFenceReq)if ((sizeof(xSyncAwaitFenceReq) >> 2) > client->req_len
) return(16)
;
2034
2035 len = client->req_len << 2;
2036 len -= sz_xSyncAwaitFenceReq4;
2037 items = len / sizeof(CARD32);
2038
2039 if (items * sizeof(CARD32) != len) {
2040 return BadLength16;
2041 }
2042 if (items == 0) {
2043 client->errorValue = items;
2044 return BadValue2;
2045 }
2046
2047 if (!(pAwaitUnion = SyncAwaitPrologue(client, items)))
2048 return BadAlloc11;
2049
2050 /* don't need to do any more memory allocation for this request! */
2051
2052 pProtocolFences = (CARD32 *) &stuff[1];
2053
2054 pAwait = &(pAwaitUnion + 1)->await; /* skip over header */
2055 for (i = 0; i < items; i++, pProtocolFences++, pAwait++) {
2056 if (*pProtocolFences == None0L) {
2057 /* this should take care of removing any triggers created by
2058 * this request that have already been registered on sync objects
2059 */
2060 FreeResource(pAwaitUnion->header.delete_id, RT_NONE((RESTYPE)0));
2061 client->errorValue = *pProtocolFences;
2062 return SyncErrorBase + XSyncBadFence2L;
2063 }
2064
2065 pAwait->trigger.pSync = NULL((void*)0);
2066 /* Provide acceptable values for these unused fields to
2067 * satisfy SyncInitTrigger's validation logic
2068 */
2069 pAwait->trigger.value_type = XSyncAbsolute;
2070 XSyncIntToValue(&pAwait->trigger.wait_value, 0)((&pAwait->trigger.wait_value)->hi=((0<0)?~0:0),
(&pAwait->trigger.wait_value)->lo=(0))
;
2071 pAwait->trigger.test_type = 0;
2072
2073 status = SyncInitTrigger(client, &pAwait->trigger,
2074 *pProtocolFences, RTFence, XSyncCAAllTrigger((1L<<0) | (1L<<1) | (1L<<2) | (1L<<3
))
);
2075 if (status != Success0) {
2076 /* this should take care of removing any triggers created by
2077 * this request that have already been registered on sync objects
2078 */
2079 FreeResource(pAwaitUnion->header.delete_id, RT_NONE((RESTYPE)0));
2080 return status;
2081 }
2082 /* this is not a mistake -- same function works for both cases */
2083 pAwait->trigger.TriggerFired = SyncAwaitTriggerFired;
2084 pAwait->trigger.CounterDestroyed = SyncAwaitTriggerFired;
2085 /* event_threshold is unused for fence syncs */
2086 XSyncIntToValue(&pAwait->event_threshold, 0)((&pAwait->event_threshold)->hi=((0<0)?~0:0),(&
pAwait->event_threshold)->lo=(0))
;
2087 pAwait->pHeader = &pAwaitUnion->header;
2088 pAwaitUnion->header.num_waitconditions++;
2089 }
2090
2091 SyncAwaitEpilogue(client, items, pAwaitUnion);
2092
2093 return client->noClientException;
2094}
2095
2096/*
2097 * ** Given an extension request, call the appropriate request procedure
2098 */
2099static int
2100ProcSyncDispatch(ClientPtr client)
2101{
2102 REQUEST(xReq)xReq *stuff = (xReq *)client->requestBuffer;
2103
2104 switch (stuff->data) {
2105 case X_SyncInitialize0:
2106 return ProcSyncInitialize(client);
2107 case X_SyncListSystemCounters1:
2108 return ProcSyncListSystemCounters(client);
2109 case X_SyncCreateCounter2:
2110 return ProcSyncCreateCounter(client);
2111 case X_SyncSetCounter3:
2112 return ProcSyncSetCounter(client);
2113 case X_SyncChangeCounter4:
2114 return ProcSyncChangeCounter(client);
2115 case X_SyncQueryCounter5:
2116 return ProcSyncQueryCounter(client);
2117 case X_SyncDestroyCounter6:
2118 return ProcSyncDestroyCounter(client);
2119 case X_SyncAwait7:
2120 return ProcSyncAwait(client);
2121 case X_SyncCreateAlarm8:
2122 return ProcSyncCreateAlarm(client);
2123 case X_SyncChangeAlarm9:
2124 return ProcSyncChangeAlarm(client);
2125 case X_SyncQueryAlarm10:
2126 return ProcSyncQueryAlarm(client);
2127 case X_SyncDestroyAlarm11:
2128 return ProcSyncDestroyAlarm(client);
2129 case X_SyncSetPriority12:
2130 return ProcSyncSetPriority(client);
2131 case X_SyncGetPriority13:
2132 return ProcSyncGetPriority(client);
2133 case X_SyncCreateFence14:
2134 return ProcSyncCreateFence(client);
2135 case X_SyncTriggerFence15:
2136 return ProcSyncTriggerFence(client);
2137 case X_SyncResetFence16:
2138 return ProcSyncResetFence(client);
2139 case X_SyncDestroyFence17:
2140 return ProcSyncDestroyFence(client);
2141 case X_SyncQueryFence18:
2142 return ProcSyncQueryFence(client);
2143 case X_SyncAwaitFence19:
2144 return ProcSyncAwaitFence(client);
2145 default:
2146 return BadRequest1;
2147 }
2148}
2149
2150/*
2151 * Boring Swapping stuff ...
2152 */
2153
2154static int
2155SProcSyncInitialize(ClientPtr client)
2156{
2157 REQUEST(xSyncInitializeReq)xSyncInitializeReq *stuff = (xSyncInitializeReq *)client->
requestBuffer
;
2158 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2159 REQUEST_SIZE_MATCH(xSyncInitializeReq)if ((sizeof(xSyncInitializeReq) >> 2) != client->req_len
) return(16)
;
2160
2161 return ProcSyncInitialize(client);
2162}
2163
2164static int
2165SProcSyncListSystemCounters(ClientPtr client)
2166{
2167 REQUEST(xSyncListSystemCountersReq)xSyncListSystemCountersReq *stuff = (xSyncListSystemCountersReq
*)client->requestBuffer
;
2168 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2169 REQUEST_SIZE_MATCH(xSyncListSystemCountersReq)if ((sizeof(xSyncListSystemCountersReq) >> 2) != client
->req_len) return(16)
;
2170
2171 return ProcSyncListSystemCounters(client);
2172}
2173
2174static int
2175SProcSyncCreateCounter(ClientPtr client)
2176{
2177 REQUEST(xSyncCreateCounterReq)xSyncCreateCounterReq *stuff = (xSyncCreateCounterReq *)client
->requestBuffer
;
2178 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2179 REQUEST_SIZE_MATCH(xSyncCreateCounterReq)if ((sizeof(xSyncCreateCounterReq) >> 2) != client->
req_len) return(16)
;
2180 swapl(&stuff->cid)do { if (sizeof(*(&stuff->cid)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->cid) & 3
) && ((uintptr_t)(&stuff->cid) & 3) == 0) *
(&stuff->cid) = lswapl(*(&stuff->cid)); else swap_uint32
((uint32_t *)(&stuff->cid)); } while (0)
;
2181 swapl(&stuff->initial_value_lo)do { if (sizeof(*(&stuff->initial_value_lo)) != 4) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&stuff->initial_value_lo
) & 3) && ((uintptr_t)(&stuff->initial_value_lo
) & 3) == 0) *(&stuff->initial_value_lo) = lswapl(
*(&stuff->initial_value_lo)); else swap_uint32((uint32_t
*)(&stuff->initial_value_lo)); } while (0)
;
2182 swapl(&stuff->initial_value_hi)do { if (sizeof(*(&stuff->initial_value_hi)) != 4) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&stuff->initial_value_hi
) & 3) && ((uintptr_t)(&stuff->initial_value_hi
) & 3) == 0) *(&stuff->initial_value_hi) = lswapl(
*(&stuff->initial_value_hi)); else swap_uint32((uint32_t
*)(&stuff->initial_value_hi)); } while (0)
;
2183
2184 return ProcSyncCreateCounter(client);
2185}
2186
2187static int
2188SProcSyncSetCounter(ClientPtr client)
2189{
2190 REQUEST(xSyncSetCounterReq)xSyncSetCounterReq *stuff = (xSyncSetCounterReq *)client->
requestBuffer
;
2191 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2192 REQUEST_SIZE_MATCH(xSyncSetCounterReq)if ((sizeof(xSyncSetCounterReq) >> 2) != client->req_len
) return(16)
;
2193 swapl(&stuff->cid)do { if (sizeof(*(&stuff->cid)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->cid) & 3
) && ((uintptr_t)(&stuff->cid) & 3) == 0) *
(&stuff->cid) = lswapl(*(&stuff->cid)); else swap_uint32
((uint32_t *)(&stuff->cid)); } while (0)
;
2194 swapl(&stuff->value_lo)do { if (sizeof(*(&stuff->value_lo)) != 4) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&stuff->value_lo
) & 3) && ((uintptr_t)(&stuff->value_lo) &
3) == 0) *(&stuff->value_lo) = lswapl(*(&stuff->
value_lo)); else swap_uint32((uint32_t *)(&stuff->value_lo
)); } while (0)
;
2195 swapl(&stuff->value_hi)do { if (sizeof(*(&stuff->value_hi)) != 4) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&stuff->value_hi
) & 3) && ((uintptr_t)(&stuff->value_hi) &
3) == 0) *(&stuff->value_hi) = lswapl(*(&stuff->
value_hi)); else swap_uint32((uint32_t *)(&stuff->value_hi
)); } while (0)
;
2196
2197 return ProcSyncSetCounter(client);
2198}
2199
2200static int
2201SProcSyncChangeCounter(ClientPtr client)
2202{
2203 REQUEST(xSyncChangeCounterReq)xSyncChangeCounterReq *stuff = (xSyncChangeCounterReq *)client
->requestBuffer
;
2204 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2205 REQUEST_SIZE_MATCH(xSyncChangeCounterReq)if ((sizeof(xSyncChangeCounterReq) >> 2) != client->
req_len) return(16)
;
2206 swapl(&stuff->cid)do { if (sizeof(*(&stuff->cid)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->cid) & 3
) && ((uintptr_t)(&stuff->cid) & 3) == 0) *
(&stuff->cid) = lswapl(*(&stuff->cid)); else swap_uint32
((uint32_t *)(&stuff->cid)); } while (0)
;
2207 swapl(&stuff->value_lo)do { if (sizeof(*(&stuff->value_lo)) != 4) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&stuff->value_lo
) & 3) && ((uintptr_t)(&stuff->value_lo) &
3) == 0) *(&stuff->value_lo) = lswapl(*(&stuff->
value_lo)); else swap_uint32((uint32_t *)(&stuff->value_lo
)); } while (0)
;
2208 swapl(&stuff->value_hi)do { if (sizeof(*(&stuff->value_hi)) != 4) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&stuff->value_hi
) & 3) && ((uintptr_t)(&stuff->value_hi) &
3) == 0) *(&stuff->value_hi) = lswapl(*(&stuff->
value_hi)); else swap_uint32((uint32_t *)(&stuff->value_hi
)); } while (0)
;
2209
2210 return ProcSyncChangeCounter(client);
2211}
2212
2213static int
2214SProcSyncQueryCounter(ClientPtr client)
2215{
2216 REQUEST(xSyncQueryCounterReq)xSyncQueryCounterReq *stuff = (xSyncQueryCounterReq *)client->
requestBuffer
;
2217 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2218 REQUEST_SIZE_MATCH(xSyncQueryCounterReq)if ((sizeof(xSyncQueryCounterReq) >> 2) != client->req_len
) return(16)
;
2219 swapl(&stuff->counter)do { if (sizeof(*(&stuff->counter)) != 4) wrong_size()
; if (__builtin_constant_p((uintptr_t)(&stuff->counter
) & 3) && ((uintptr_t)(&stuff->counter) &
3) == 0) *(&stuff->counter) = lswapl(*(&stuff->
counter)); else swap_uint32((uint32_t *)(&stuff->counter
)); } while (0)
;
2220
2221 return ProcSyncQueryCounter(client);
2222}
2223
2224static int
2225SProcSyncDestroyCounter(ClientPtr client)
2226{
2227 REQUEST(xSyncDestroyCounterReq)xSyncDestroyCounterReq *stuff = (xSyncDestroyCounterReq *)client
->requestBuffer
;
2228 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2229 REQUEST_SIZE_MATCH(xSyncDestroyCounterReq)if ((sizeof(xSyncDestroyCounterReq) >> 2) != client->
req_len) return(16)
;
2230 swapl(&stuff->counter)do { if (sizeof(*(&stuff->counter)) != 4) wrong_size()
; if (__builtin_constant_p((uintptr_t)(&stuff->counter
) & 3) && ((uintptr_t)(&stuff->counter) &
3) == 0) *(&stuff->counter) = lswapl(*(&stuff->
counter)); else swap_uint32((uint32_t *)(&stuff->counter
)); } while (0)
;
2231
2232 return ProcSyncDestroyCounter(client);
2233}
2234
2235static int
2236SProcSyncAwait(ClientPtr client)
2237{
2238 REQUEST(xSyncAwaitReq)xSyncAwaitReq *stuff = (xSyncAwaitReq *)client->requestBuffer;
2239 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2240 REQUEST_AT_LEAST_SIZE(xSyncAwaitReq)if ((sizeof(xSyncAwaitReq) >> 2) > client->req_len
) return(16)
;
2241 SwapRestL(stuff)SwapLongs((CARD32 *)(stuff + 1), (client->req_len - (sizeof
(*stuff) >> 2)))
;
2242
2243 return ProcSyncAwait(client);
2244}
2245
2246static int
2247SProcSyncCreateAlarm(ClientPtr client)
2248{
2249 REQUEST(xSyncCreateAlarmReq)xSyncCreateAlarmReq *stuff = (xSyncCreateAlarmReq *)client->
requestBuffer
;
2250 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2251 REQUEST_AT_LEAST_SIZE(xSyncCreateAlarmReq)if ((sizeof(xSyncCreateAlarmReq) >> 2) > client->
req_len ) return(16)
;
2252 swapl(&stuff->id)do { if (sizeof(*(&stuff->id)) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&stuff->id) & 3) &&
((uintptr_t)(&stuff->id) & 3) == 0) *(&stuff->
id) = lswapl(*(&stuff->id)); else swap_uint32((uint32_t
*)(&stuff->id)); } while (0)
;
2253 swapl(&stuff->valueMask)do { if (sizeof(*(&stuff->valueMask)) != 4) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&stuff->valueMask
) & 3) && ((uintptr_t)(&stuff->valueMask) &
3) == 0) *(&stuff->valueMask) = lswapl(*(&stuff->
valueMask)); else swap_uint32((uint32_t *)(&stuff->valueMask
)); } while (0)
;
2254 SwapRestL(stuff)SwapLongs((CARD32 *)(stuff + 1), (client->req_len - (sizeof
(*stuff) >> 2)))
;
2255
2256 return ProcSyncCreateAlarm(client);
2257}
2258
2259static int
2260SProcSyncChangeAlarm(ClientPtr client)
2261{
2262 REQUEST(xSyncChangeAlarmReq)xSyncChangeAlarmReq *stuff = (xSyncChangeAlarmReq *)client->
requestBuffer
;
2263 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2264 REQUEST_AT_LEAST_SIZE(xSyncChangeAlarmReq)if ((sizeof(xSyncChangeAlarmReq) >> 2) > client->
req_len ) return(16)
;
2265 swapl(&stuff->alarm)do { if (sizeof(*(&stuff->alarm)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->alarm) &
3) && ((uintptr_t)(&stuff->alarm) & 3) ==
0) *(&stuff->alarm) = lswapl(*(&stuff->alarm))
; else swap_uint32((uint32_t *)(&stuff->alarm)); } while
(0)
;
2266 swapl(&stuff->valueMask)do { if (sizeof(*(&stuff->valueMask)) != 4) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&stuff->valueMask
) & 3) && ((uintptr_t)(&stuff->valueMask) &
3) == 0) *(&stuff->valueMask) = lswapl(*(&stuff->
valueMask)); else swap_uint32((uint32_t *)(&stuff->valueMask
)); } while (0)
;
2267 SwapRestL(stuff)SwapLongs((CARD32 *)(stuff + 1), (client->req_len - (sizeof
(*stuff) >> 2)))
;
2268 return ProcSyncChangeAlarm(client);
2269}
2270
2271static int
2272SProcSyncQueryAlarm(ClientPtr client)
2273{
2274 REQUEST(xSyncQueryAlarmReq)xSyncQueryAlarmReq *stuff = (xSyncQueryAlarmReq *)client->
requestBuffer
;
2275 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2276 REQUEST_SIZE_MATCH(xSyncQueryAlarmReq)if ((sizeof(xSyncQueryAlarmReq) >> 2) != client->req_len
) return(16)
;
2277 swapl(&stuff->alarm)do { if (sizeof(*(&stuff->alarm)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->alarm) &
3) && ((uintptr_t)(&stuff->alarm) & 3) ==
0) *(&stuff->alarm) = lswapl(*(&stuff->alarm))
; else swap_uint32((uint32_t *)(&stuff->alarm)); } while
(0)
;
2278
2279 return ProcSyncQueryAlarm(client);
2280}
2281
2282static int
2283SProcSyncDestroyAlarm(ClientPtr client)
2284{
2285 REQUEST(xSyncDestroyAlarmReq)xSyncDestroyAlarmReq *stuff = (xSyncDestroyAlarmReq *)client->
requestBuffer
;
2286 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2287 REQUEST_SIZE_MATCH(xSyncDestroyAlarmReq)if ((sizeof(xSyncDestroyAlarmReq) >> 2) != client->req_len
) return(16)
;
2288 swapl(&stuff->alarm)do { if (sizeof(*(&stuff->alarm)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->alarm) &
3) && ((uintptr_t)(&stuff->alarm) & 3) ==
0) *(&stuff->alarm) = lswapl(*(&stuff->alarm))
; else swap_uint32((uint32_t *)(&stuff->alarm)); } while
(0)
;
2289
2290 return ProcSyncDestroyAlarm(client);
2291}
2292
2293static int
2294SProcSyncSetPriority(ClientPtr client)
2295{
2296 REQUEST(xSyncSetPriorityReq)xSyncSetPriorityReq *stuff = (xSyncSetPriorityReq *)client->
requestBuffer
;
2297 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2298 REQUEST_SIZE_MATCH(xSyncSetPriorityReq)if ((sizeof(xSyncSetPriorityReq) >> 2) != client->req_len
) return(16)
;
2299 swapl(&stuff->id)do { if (sizeof(*(&stuff->id)) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&stuff->id) & 3) &&
((uintptr_t)(&stuff->id) & 3) == 0) *(&stuff->
id) = lswapl(*(&stuff->id)); else swap_uint32((uint32_t
*)(&stuff->id)); } while (0)
;
2300 swapl(&stuff->priority)do { if (sizeof(*(&stuff->priority)) != 4) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&stuff->priority
) & 3) && ((uintptr_t)(&stuff->priority) &
3) == 0) *(&stuff->priority) = lswapl(*(&stuff->
priority)); else swap_uint32((uint32_t *)(&stuff->priority
)); } while (0)
;
2301
2302 return ProcSyncSetPriority(client);
2303}
2304
2305static int
2306SProcSyncGetPriority(ClientPtr client)
2307{
2308 REQUEST(xSyncGetPriorityReq)xSyncGetPriorityReq *stuff = (xSyncGetPriorityReq *)client->
requestBuffer
;
2309 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2310 REQUEST_SIZE_MATCH(xSyncGetPriorityReq)if ((sizeof(xSyncGetPriorityReq) >> 2) != client->req_len
) return(16)
;
2311 swapl(&stuff->id)do { if (sizeof(*(&stuff->id)) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&stuff->id) & 3) &&
((uintptr_t)(&stuff->id) & 3) == 0) *(&stuff->
id) = lswapl(*(&stuff->id)); else swap_uint32((uint32_t
*)(&stuff->id)); } while (0)
;
2312
2313 return ProcSyncGetPriority(client);
2314}
2315
2316static int
2317SProcSyncCreateFence(ClientPtr client)
2318{
2319 REQUEST(xSyncCreateFenceReq)xSyncCreateFenceReq *stuff = (xSyncCreateFenceReq *)client->
requestBuffer
;
2320 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2321 REQUEST_SIZE_MATCH(xSyncCreateFenceReq)if ((sizeof(xSyncCreateFenceReq) >> 2) != client->req_len
) return(16)
;
2322 swapl(&stuff->fid)do { if (sizeof(*(&stuff->fid)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->fid) & 3
) && ((uintptr_t)(&stuff->fid) & 3) == 0) *
(&stuff->fid) = lswapl(*(&stuff->fid)); else swap_uint32
((uint32_t *)(&stuff->fid)); } while (0)
;
2323
2324 return ProcSyncCreateFence(client);
2325}
2326
2327static int
2328SProcSyncTriggerFence(ClientPtr client)
2329{
2330 REQUEST(xSyncTriggerFenceReq)xSyncTriggerFenceReq *stuff = (xSyncTriggerFenceReq *)client->
requestBuffer
;
2331 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2332 REQUEST_SIZE_MATCH(xSyncTriggerFenceReq)if ((sizeof(xSyncTriggerFenceReq) >> 2) != client->req_len
) return(16)
;
2333 swapl(&stuff->fid)do { if (sizeof(*(&stuff->fid)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->fid) & 3
) && ((uintptr_t)(&stuff->fid) & 3) == 0) *
(&stuff->fid) = lswapl(*(&stuff->fid)); else swap_uint32
((uint32_t *)(&stuff->fid)); } while (0)
;
2334
2335 return ProcSyncTriggerFence(client);
2336}
2337
2338static int
2339SProcSyncResetFence(ClientPtr client)
2340{
2341 REQUEST(xSyncResetFenceReq)xSyncResetFenceReq *stuff = (xSyncResetFenceReq *)client->
requestBuffer
;
2342 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2343 REQUEST_SIZE_MATCH(xSyncResetFenceReq)if ((sizeof(xSyncResetFenceReq) >> 2) != client->req_len
) return(16)
;
2344 swapl(&stuff->fid)do { if (sizeof(*(&stuff->fid)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->fid) & 3
) && ((uintptr_t)(&stuff->fid) & 3) == 0) *
(&stuff->fid) = lswapl(*(&stuff->fid)); else swap_uint32
((uint32_t *)(&stuff->fid)); } while (0)
;
2345
2346 return ProcSyncResetFence(client);
2347}
2348
2349static int
2350SProcSyncDestroyFence(ClientPtr client)
2351{
2352 REQUEST(xSyncDestroyFenceReq)xSyncDestroyFenceReq *stuff = (xSyncDestroyFenceReq *)client->
requestBuffer
;
2353 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2354 REQUEST_SIZE_MATCH(xSyncDestroyFenceReq)if ((sizeof(xSyncDestroyFenceReq) >> 2) != client->req_len
) return(16)
;
2355 swapl(&stuff->fid)do { if (sizeof(*(&stuff->fid)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->fid) & 3
) && ((uintptr_t)(&stuff->fid) & 3) == 0) *
(&stuff->fid) = lswapl(*(&stuff->fid)); else swap_uint32
((uint32_t *)(&stuff->fid)); } while (0)
;
2356
2357 return ProcSyncDestroyFence(client);
2358}
2359
2360static int
2361SProcSyncQueryFence(ClientPtr client)
2362{
2363 REQUEST(xSyncQueryFenceReq)xSyncQueryFenceReq *stuff = (xSyncQueryFenceReq *)client->
requestBuffer
;
2364 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2365 REQUEST_SIZE_MATCH(xSyncQueryFenceReq)if ((sizeof(xSyncQueryFenceReq) >> 2) != client->req_len
) return(16)
;
2366 swapl(&stuff->fid)do { if (sizeof(*(&stuff->fid)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->fid) & 3
) && ((uintptr_t)(&stuff->fid) & 3) == 0) *
(&stuff->fid) = lswapl(*(&stuff->fid)); else swap_uint32
((uint32_t *)(&stuff->fid)); } while (0)
;
2367
2368 return ProcSyncQueryFence(client);
2369}
2370
2371static int
2372SProcSyncAwaitFence(ClientPtr client)
2373{
2374 REQUEST(xSyncAwaitFenceReq)xSyncAwaitFenceReq *stuff = (xSyncAwaitFenceReq *)client->
requestBuffer
;
2375 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
2376 REQUEST_AT_LEAST_SIZE(xSyncAwaitFenceReq)if ((sizeof(xSyncAwaitFenceReq) >> 2) > client->req_len
) return(16)
;
2377 SwapRestL(stuff)SwapLongs((CARD32 *)(stuff + 1), (client->req_len - (sizeof
(*stuff) >> 2)))
;
2378
2379 return ProcSyncAwaitFence(client);
2380}
2381
2382static int
2383SProcSyncDispatch(ClientPtr client)
2384{
2385 REQUEST(xReq)xReq *stuff = (xReq *)client->requestBuffer;
2386
2387 switch (stuff->data) {
2388 case X_SyncInitialize0:
2389 return SProcSyncInitialize(client);
2390 case X_SyncListSystemCounters1:
2391 return SProcSyncListSystemCounters(client);
2392 case X_SyncCreateCounter2:
2393 return SProcSyncCreateCounter(client);
2394 case X_SyncSetCounter3:
2395 return SProcSyncSetCounter(client);
2396 case X_SyncChangeCounter4:
2397 return SProcSyncChangeCounter(client);
2398 case X_SyncQueryCounter5:
2399 return SProcSyncQueryCounter(client);
2400 case X_SyncDestroyCounter6:
2401 return SProcSyncDestroyCounter(client);
2402 case X_SyncAwait7:
2403 return SProcSyncAwait(client);
2404 case X_SyncCreateAlarm8:
2405 return SProcSyncCreateAlarm(client);
2406 case X_SyncChangeAlarm9:
2407 return SProcSyncChangeAlarm(client);
2408 case X_SyncQueryAlarm10:
2409 return SProcSyncQueryAlarm(client);
2410 case X_SyncDestroyAlarm11:
2411 return SProcSyncDestroyAlarm(client);
2412 case X_SyncSetPriority12:
2413 return SProcSyncSetPriority(client);
2414 case X_SyncGetPriority13:
2415 return SProcSyncGetPriority(client);
2416 case X_SyncCreateFence14:
2417 return SProcSyncCreateFence(client);
2418 case X_SyncTriggerFence15:
2419 return SProcSyncTriggerFence(client);
2420 case X_SyncResetFence16:
2421 return SProcSyncResetFence(client);
2422 case X_SyncDestroyFence17:
2423 return SProcSyncDestroyFence(client);
2424 case X_SyncQueryFence18:
2425 return SProcSyncQueryFence(client);
2426 case X_SyncAwaitFence19:
2427 return SProcSyncAwaitFence(client);
2428 default:
2429 return BadRequest1;
2430 }
2431}
2432
2433/*
2434 * Event Swapping
2435 */
2436
2437static void
2438SCounterNotifyEvent(xSyncCounterNotifyEvent * from,
2439 xSyncCounterNotifyEvent * to)
2440{
2441 to->type = from->type;
2442 to->kind = from->kind;
2443 cpswaps(from->sequenceNumber, to->sequenceNumber)do { if (sizeof((from->sequenceNumber)) != 2 || sizeof((to
->sequenceNumber)) != 2) wrong_size(); (to->sequenceNumber
) = lswaps((from->sequenceNumber)); } while (0)
;
2444 cpswapl(from->counter, to->counter)do { if (sizeof((from->counter)) != 4 || sizeof((to->counter
)) != 4) wrong_size(); (to->counter) = lswapl((from->counter
)); } while (0)
;
2445 cpswapl(from->wait_value_lo, to->wait_value_lo)do { if (sizeof((from->wait_value_lo)) != 4 || sizeof((to->
wait_value_lo)) != 4) wrong_size(); (to->wait_value_lo) = lswapl
((from->wait_value_lo)); } while (0)
;
2446 cpswapl(from->wait_value_hi, to->wait_value_hi)do { if (sizeof((from->wait_value_hi)) != 4 || sizeof((to->
wait_value_hi)) != 4) wrong_size(); (to->wait_value_hi) = lswapl
((from->wait_value_hi)); } while (0)
;
2447 cpswapl(from->counter_value_lo, to->counter_value_lo)do { if (sizeof((from->counter_value_lo)) != 4 || sizeof((
to->counter_value_lo)) != 4) wrong_size(); (to->counter_value_lo
) = lswapl((from->counter_value_lo)); } while (0)
;
2448 cpswapl(from->counter_value_hi, to->counter_value_hi)do { if (sizeof((from->counter_value_hi)) != 4 || sizeof((
to->counter_value_hi)) != 4) wrong_size(); (to->counter_value_hi
) = lswapl((from->counter_value_hi)); } while (0)
;
2449 cpswapl(from->time, to->time)do { if (sizeof((from->time)) != 4 || sizeof((to->time)
) != 4) wrong_size(); (to->time) = lswapl((from->time))
; } while (0)
;
2450 cpswaps(from->count, to->count)do { if (sizeof((from->count)) != 2 || sizeof((to->count
)) != 2) wrong_size(); (to->count) = lswaps((from->count
)); } while (0)
;
2451 to->destroyed = from->destroyed;
2452}
2453
2454static void
2455SAlarmNotifyEvent(xSyncAlarmNotifyEvent * from, xSyncAlarmNotifyEvent * to)
2456{
2457 to->type = from->type;
2458 to->kind = from->kind;
2459 cpswaps(from->sequenceNumber, to->sequenceNumber)do { if (sizeof((from->sequenceNumber)) != 2 || sizeof((to
->sequenceNumber)) != 2) wrong_size(); (to->sequenceNumber
) = lswaps((from->sequenceNumber)); } while (0)
;
2460 cpswapl(from->alarm, to->alarm)do { if (sizeof((from->alarm)) != 4 || sizeof((to->alarm
)) != 4) wrong_size(); (to->alarm) = lswapl((from->alarm
)); } while (0)
;
2461 cpswapl(from->counter_value_lo, to->counter_value_lo)do { if (sizeof((from->counter_value_lo)) != 4 || sizeof((
to->counter_value_lo)) != 4) wrong_size(); (to->counter_value_lo
) = lswapl((from->counter_value_lo)); } while (0)
;
2462 cpswapl(from->counter_value_hi, to->counter_value_hi)do { if (sizeof((from->counter_value_hi)) != 4 || sizeof((
to->counter_value_hi)) != 4) wrong_size(); (to->counter_value_hi
) = lswapl((from->counter_value_hi)); } while (0)
;
2463 cpswapl(from->alarm_value_lo, to->alarm_value_lo)do { if (sizeof((from->alarm_value_lo)) != 4 || sizeof((to
->alarm_value_lo)) != 4) wrong_size(); (to->alarm_value_lo
) = lswapl((from->alarm_value_lo)); } while (0)
;
2464 cpswapl(from->alarm_value_hi, to->alarm_value_hi)do { if (sizeof((from->alarm_value_hi)) != 4 || sizeof((to
->alarm_value_hi)) != 4) wrong_size(); (to->alarm_value_hi
) = lswapl((from->alarm_value_hi)); } while (0)
;
2465 cpswapl(from->time, to->time)do { if (sizeof((from->time)) != 4 || sizeof((to->time)
) != 4) wrong_size(); (to->time) = lswapl((from->time))
; } while (0)
;
2466 to->state = from->state;
2467}
2468
2469/*
2470 * ** Close everything down. ** This is fairly simple for now.
2471 */
2472/* ARGSUSED */
2473static void
2474SyncResetProc(ExtensionEntry * extEntry)
2475{
2476 RTCounter = 0;
2477}
2478
2479/*
2480 * ** Initialise the extension.
2481 */
2482void
2483SyncExtensionInit(void)
2484{
2485 ExtensionEntry *extEntry;
2486 int s;
2487
2488 for (s = 0; s < screenInfo.numScreens; s++)
2489 miSyncSetup(screenInfo.screens[s]);
2490
2491 RTCounter = CreateNewResourceType(FreeCounter, "SyncCounter");
2492 xorg_list_init(&SysCounterList);
2493 RTAlarm = CreateNewResourceType(FreeAlarm, "SyncAlarm");
2494 RTAwait = CreateNewResourceType(FreeAwait, "SyncAwait");
2495 RTFence = CreateNewResourceType(FreeFence, "SyncFence");
2496 if (RTAwait)
2497 RTAwait |= RC_NEVERRETAIN((RESTYPE)1<<29);
2498 RTAlarmClient = CreateNewResourceType(FreeAlarmClient, "SyncAlarmClient");
2499 if (RTAlarmClient)
2500 RTAlarmClient |= RC_NEVERRETAIN((RESTYPE)1<<29);
2501
2502 if (RTCounter == 0 || RTAwait == 0 || RTAlarm == 0 ||
2503 RTAlarmClient == 0 ||
2504 (extEntry = AddExtension(SYNC_NAME"SYNC",
2505 XSyncNumberEvents2L, XSyncNumberErrors(2L + 1),
2506 ProcSyncDispatch, SProcSyncDispatch,
2507 SyncResetProc, StandardMinorOpcode)) == NULL((void*)0)) {
2508 ErrorF("Sync Extension %d.%d failed to Initialise\n",
2509 SYNC_MAJOR_VERSION3, SYNC_MINOR_VERSION1);
2510 return;
2511 }
2512
2513 SyncEventBase = extEntry->eventBase;
2514 SyncErrorBase = extEntry->errorBase;
2515 EventSwapVector[SyncEventBase + XSyncCounterNotify0] =
2516 (EventSwapPtr) SCounterNotifyEvent;
2517 EventSwapVector[SyncEventBase + XSyncAlarmNotify1] =
2518 (EventSwapPtr) SAlarmNotifyEvent;
2519
2520 SetResourceTypeErrorValue(RTCounter, SyncErrorBase + XSyncBadCounter0L);
2521 SetResourceTypeErrorValue(RTAlarm, SyncErrorBase + XSyncBadAlarm1L);
2522 SetResourceTypeErrorValue(RTFence, SyncErrorBase + XSyncBadFence2L);
2523
2524 /*
2525 * Although SERVERTIME is implemented by the OS layer, we initialise it
2526 * here because doing it in OsInit() is too early. The resource database
2527 * is not initialised when OsInit() is called. This is just about OK
2528 * because there is always a servertime counter.
2529 */
2530 SyncInitServerTime();
2531 SyncInitIdleTime();
2532
2533#ifdef DEBUG
2534 fprintf(stderr__stderrp, "Sync Extension %d.%d\n",
2535 SYNC_MAJOR_VERSION3, SYNC_MINOR_VERSION1);
2536#endif
2537}
2538
2539/*
2540 * ***** SERVERTIME implementation - should go in its own file in OS directory?
2541 */
2542
2543static void *ServertimeCounter;
2544static XSyncValue Now;
2545static XSyncValue *pnext_time;
2546
2547#define GetTime(){ unsigned long millis = GetTimeInMillis(); unsigned long maxis
= ((Now).hi); if (millis < ((Now).lo)) maxis++; ((&Now
)->lo = (millis), (&Now)->hi = (maxis));}
\
2548{\
2549 unsigned long millis = GetTimeInMillis();\
2550 unsigned long maxis = XSyncValueHigh32(Now)((Now).hi);\
2551 if (millis < XSyncValueLow32(Now)((Now).lo)) maxis++;\
2552 XSyncIntsToValue(&Now, millis, maxis)((&Now)->lo = (millis), (&Now)->hi = (maxis));\
2553}
2554
2555/*
2556*** Server Block Handler
2557*** code inspired by multibuffer extension (now deprecated)
2558 */
2559 /*ARGSUSED*/ static void
2560ServertimeBlockHandler(void *env, struct timeval **wt, void *LastSelectMask)
2561{
2562 XSyncValue delay;
2563 unsigned long timeout;
2564
2565 if (pnext_time) {
2566 GetTime(){ unsigned long millis = GetTimeInMillis(); unsigned long maxis
= ((Now).hi); if (millis < ((Now).lo)) maxis++; ((&Now
)->lo = (millis), (&Now)->hi = (maxis));}
;
2567
2568 if (XSyncValueGreaterOrEqual(Now, *pnext_time)((Now).hi>(*pnext_time).hi || ((Now).hi==(*pnext_time).hi &&
(Now).lo>=(*pnext_time).lo))
) {
2569 timeout = 0;
2570 }
2571 else {
2572 Bool overflow;
2573
2574 XSyncValueSubtract(&delay, *pnext_time, Now, &overflow){ int t = (*pnext_time).lo; Bool signa = (((*pnext_time).hi &
0x80000000) ? 1 : 0); Bool signb = (((Now).hi & 0x80000000
) ? 1 : 0); ((&delay)->lo = (*pnext_time).lo - (Now).lo
); ((&delay)->hi = (*pnext_time).hi - (Now).hi); if (t
<(&delay)->lo) (&delay)->hi--; *&overflow
= ((signa == signb) && !(signa == (((*&delay).hi
& 0x80000000) ? 1 : 0))); }
;
2575 (void) overflow;
2576 timeout = XSyncValueLow32(delay)((delay).lo);
2577 }
2578 AdjustWaitForDelay(wt, timeout); /* os/utils.c */
2579 }
2580}
2581
2582/*
2583*** Wakeup Handler
2584 */
2585 /*ARGSUSED*/ static void
2586ServertimeWakeupHandler(void *env, int rc, void *LastSelectMask)
2587{
2588 if (pnext_time) {
2589 GetTime(){ unsigned long millis = GetTimeInMillis(); unsigned long maxis
= ((Now).hi); if (millis < ((Now).lo)) maxis++; ((&Now
)->lo = (millis), (&Now)->hi = (maxis));}
;
2590
2591 if (XSyncValueGreaterOrEqual(Now, *pnext_time)((Now).hi>(*pnext_time).hi || ((Now).hi==(*pnext_time).hi &&
(Now).lo>=(*pnext_time).lo))
) {
2592 SyncChangeCounter(ServertimeCounter, Now);
2593 }
2594 }
2595}
2596
2597static void
2598ServertimeQueryValue(void *pCounter, CARD64XSyncValue * pValue_return)
2599{
2600 GetTime(){ unsigned long millis = GetTimeInMillis(); unsigned long maxis
= ((Now).hi); if (millis < ((Now).lo)) maxis++; ((&Now
)->lo = (millis), (&Now)->hi = (maxis));}
;
2601 *pValue_return = Now;
2602}
2603
2604static void
2605ServertimeBracketValues(void *pCounter, CARD64XSyncValue * pbracket_less,
2606 CARD64XSyncValue * pbracket_greater)
2607{
2608 if (!pnext_time && pbracket_greater) {
2609 RegisterBlockAndWakeupHandlers(ServertimeBlockHandler,
2610 ServertimeWakeupHandler, NULL((void*)0));
2611 }
2612 else if (pnext_time && !pbracket_greater) {
2613 RemoveBlockAndWakeupHandlers(ServertimeBlockHandler,
2614 ServertimeWakeupHandler, NULL((void*)0));
2615 }
2616 pnext_time = pbracket_greater;
2617}
2618
2619static void
2620SyncInitServerTime(void)
2621{
2622 CARD64XSyncValue resolution;
2623
2624 XSyncIntsToValue(&Now, GetTimeInMillis(), 0)((&Now)->lo = (GetTimeInMillis()), (&Now)->hi =
(0))
;
2625 XSyncIntToValue(&resolution, 4)((&resolution)->hi=((4<0)?~0:0),(&resolution)->
lo=(4))
;
2626 ServertimeCounter = SyncCreateSystemCounter("SERVERTIME", Now, resolution,
2627 XSyncCounterNeverDecreases,
2628 ServertimeQueryValue,
2629 ServertimeBracketValues);
2630 pnext_time = NULL((void*)0);
2631}
2632
2633/*
2634 * IDLETIME implementation
2635 */
2636
2637typedef struct {
2638 XSyncValue *value_less;
2639 XSyncValue *value_greater;
2640 int deviceid;
2641} IdleCounterPriv;
2642
2643static void
2644IdleTimeQueryValue(void *pCounter, CARD64XSyncValue * pValue_return)
2645{
2646 int deviceid;
2647 CARD32 idle;
2648
2649 if (pCounter) {
2650 SyncCounter *counter = pCounter;
2651 IdleCounterPriv *priv = SysCounterGetPrivate(counter);
2652 deviceid = priv->deviceid;
2653 }
2654 else
2655 deviceid = XIAllDevices0;
2656 idle = GetTimeInMillis() - LastEventTime(deviceid).milliseconds;
2657 XSyncIntsToValue(pValue_return, idle, 0)((pValue_return)->lo = (idle), (pValue_return)->hi = (0
))
;
2658}
2659
2660static void
2661IdleTimeBlockHandler(void *pCounter, struct timeval **wt, void *LastSelectMask)
2662{
2663 SyncCounter *counter = pCounter;
2664 IdleCounterPriv *priv = SysCounterGetPrivate(counter);
2665 XSyncValue *less = priv->value_less,
2666 *greater = priv->value_greater;
2667 XSyncValue idle, old_idle;
2668 SyncTriggerList *list = counter->sync.pTriglist;
Value stored to 'list' during its initialization is never read
2669 SyncTrigger *trig;
2670
2671 if (!less && !greater)
2672 return;
2673
2674 old_idle = counter->value;
2675 IdleTimeQueryValue(counter, &idle);
2676 counter->value = idle; /* push, so CheckTrigger works */
2677
2678 /**
2679 * There's an indefinite amount of time between ProcessInputEvents()
2680 * where the idle time is reset and the time we actually get here. idle
2681 * may be past the lower bracket if we dawdled with the events, so
2682 * check for whether we did reset and bomb out of select immediately.
2683 */
2684 if (less && XSyncValueGreaterThan(idle, *less)((idle).hi>(*less).hi || ((idle).hi==(*less).hi &&
(idle).lo>(*less).lo))
&&
2685 LastEventTimeWasReset(priv->deviceid)) {
2686 AdjustWaitForDelay(wt, 0);
2687 } else if (less && XSyncValueLessOrEqual(idle, *less)((idle).hi<(*less).hi || ((idle).hi==(*less).hi &&
(idle).lo<=(*less).lo))
) {
2688 /*
2689 * We've been idle for less than the threshold value, and someone
2690 * wants to know about that, but now we need to know whether they
2691 * want level or edge trigger. Check the trigger list against the
2692 * current idle time, and if any succeed, bomb out of select()
2693 * immediately so we can reschedule.
2694 */
2695
2696 for (list = counter->sync.pTriglist; list; list = list->next) {
2697 trig = list->pTrigger;
2698 if (trig->CheckTrigger(trig, old_idle)) {
2699 AdjustWaitForDelay(wt, 0);
2700 break;
2701 }
2702 }
2703 /*
2704 * We've been called exactly on the idle time, but we have a
2705 * NegativeTransition trigger which requires a transition from an
2706 * idle time greater than this. Schedule a wakeup for the next
2707 * millisecond so we won't miss a transition.
2708 */
2709 if (XSyncValueEqual(idle, *less)((idle).lo==(*less).lo && (idle).hi==(*less).hi))
2710 AdjustWaitForDelay(wt, 1);
2711 }
2712 else if (greater) {
2713 /*
2714 * There's a threshold in the positive direction. If we've been
2715 * idle less than it, schedule a wakeup for sometime in the future.
2716 * If we've been idle more than it, and someone wants to know about
2717 * that level-triggered, schedule an immediate wakeup.
2718 */
2719
2720 if (XSyncValueLessThan(idle, *greater)((idle).hi<(*greater).hi || ((idle).hi==(*greater).hi &&
(idle).lo<(*greater).lo))
) {
2721 XSyncValue value;
2722 Bool overflow;
2723
2724 XSyncValueSubtract(&value, *greater, idle, &overflow){ int t = (*greater).lo; Bool signa = (((*greater).hi & 0x80000000
) ? 1 : 0); Bool signb = (((idle).hi & 0x80000000) ? 1 : 0
); ((&value)->lo = (*greater).lo - (idle).lo); ((&
value)->hi = (*greater).hi - (idle).hi); if (t<(&value
)->lo) (&value)->hi--; *&overflow = ((signa == signb
) && !(signa == (((*&value).hi & 0x80000000) ?
1 : 0))); }
;
2725 AdjustWaitForDelay(wt, XSyncValueLow32(value)((value).lo));
2726 }
2727 else {
2728 for (list = counter->sync.pTriglist; list;
2729 list = list->next) {
2730 trig = list->pTrigger;
2731 if (trig->CheckTrigger(trig, old_idle)) {
2732 AdjustWaitForDelay(wt, 0);
2733 break;
2734 }
2735 }
2736 }
2737 }
2738
2739 counter->value = old_idle; /* pop */
2740}
2741
2742static void
2743IdleTimeCheckBrackets(SyncCounter *counter, XSyncValue idle, XSyncValue *less, XSyncValue *greater)
2744{
2745 if ((greater && XSyncValueGreaterOrEqual(idle, *greater)((idle).hi>(*greater).hi || ((idle).hi==(*greater).hi &&
(idle).lo>=(*greater).lo))
) ||
2746 (less && XSyncValueLessOrEqual(idle, *less)((idle).hi<(*less).hi || ((idle).hi==(*less).hi &&
(idle).lo<=(*less).lo))
)) {
2747 SyncChangeCounter(counter, idle);
2748 }
2749 else
2750 SyncUpdateCounter(counter, idle);
2751}
2752
2753static void
2754IdleTimeWakeupHandler(void *pCounter, int rc, void *LastSelectMask)
2755{
2756 SyncCounter *counter = pCounter;
2757 IdleCounterPriv *priv = SysCounterGetPrivate(counter);
2758 XSyncValue *less = priv->value_less,
2759 *greater = priv->value_greater;
2760 XSyncValue idle;
2761
2762 if (!less && !greater)
2763 return;
2764
2765 IdleTimeQueryValue(pCounter, &idle);
2766
2767 /*
2768 There is no guarantee for the WakeupHandler to be called within a specific
2769 timeframe. Idletime may go to 0, but by the time we get here, it may be
2770 non-zero and alarms for a pos. transition on 0 won't get triggered.
2771 https://bugs.freedesktop.org/show_bug.cgi?id=70476
2772 */
2773 if (LastEventTimeWasReset(priv->deviceid)) {
2774 LastEventTimeToggleResetFlag(priv->deviceid, FALSE0);
2775 if (!XSyncValueIsZero(idle)((idle).lo==0 && (idle).hi==0)) {
2776 XSyncValue zero;
2777 XSyncIntsToValue(&zero, 0, 0)((&zero)->lo = (0), (&zero)->hi = (0));
2778 IdleTimeCheckBrackets(counter, zero, less, greater);
2779 less = priv->value_less;
2780 greater = priv->value_greater;
2781 }
2782 }
2783
2784 IdleTimeCheckBrackets(counter, idle, less, greater);
2785}
2786
2787static void
2788IdleTimeBracketValues(void *pCounter, CARD64XSyncValue * pbracket_less,
2789 CARD64XSyncValue * pbracket_greater)
2790{
2791 SyncCounter *counter = pCounter;
2792 IdleCounterPriv *priv = SysCounterGetPrivate(counter);
2793 XSyncValue *less = priv->value_less,
2794 *greater = priv->value_greater;
2795 Bool registered = (less || greater);
2796
2797 if (registered && !pbracket_less && !pbracket_greater) {
2798 RemoveBlockAndWakeupHandlers(IdleTimeBlockHandler,
2799 IdleTimeWakeupHandler, pCounter);
2800 }
2801 else if (!registered && (pbracket_less || pbracket_greater)) {
2802 /* Reset flag must be zero so we don't force a idle timer reset on
2803 the first wakeup */
2804 LastEventTimeToggleResetAll(FALSE0);
2805 RegisterBlockAndWakeupHandlers(IdleTimeBlockHandler,
2806 IdleTimeWakeupHandler, pCounter);
2807 }
2808
2809 priv->value_greater = pbracket_greater;
2810 priv->value_less = pbracket_less;
2811}
2812
2813static SyncCounter*
2814init_system_idle_counter(const char *name, int deviceid)
2815{
2816 CARD64XSyncValue resolution;
2817 XSyncValue idle;
2818 SyncCounter *idle_time_counter;
2819
2820 IdleTimeQueryValue(NULL((void*)0), &idle);
2821 XSyncIntToValue(&resolution, 4)((&resolution)->hi=((4<0)?~0:0),(&resolution)->
lo=(4))
;
2822
2823 idle_time_counter = SyncCreateSystemCounter(name, idle, resolution,
2824 XSyncCounterUnrestricted,
2825 IdleTimeQueryValue,
2826 IdleTimeBracketValues);
2827
2828 if (idle_time_counter != NULL((void*)0)) {
2829 IdleCounterPriv *priv = malloc(sizeof(IdleCounterPriv));
2830
2831 priv->value_less = priv->value_greater = NULL((void*)0);
2832 priv->deviceid = deviceid;
2833
2834 idle_time_counter->pSysCounterInfo->private = priv;
2835 }
2836
2837 return idle_time_counter;
2838}
2839
2840static void
2841SyncInitIdleTime(void)
2842{
2843 init_system_idle_counter("IDLETIME", XIAllDevices0);
2844}
2845
2846SyncCounter*
2847SyncInitDeviceIdleTime(DeviceIntPtr dev)
2848{
2849 char timer_name[64];
2850 sprintf(timer_name, "DEVICEIDLETIME %d", dev->id)__builtin___sprintf_chk (timer_name, 0, __builtin_object_size
(timer_name, 2 > 1 ? 1 : 0), "DEVICEIDLETIME %d", dev->
id)
;
2851
2852 return init_system_idle_counter(timer_name, dev->id);
2853}
2854
2855void SyncRemoveDeviceIdleTime(SyncCounter *counter)
2856{
2857 /* FreeAllResources() frees all system counters before the devices are
2858 shut down, check if there are any left before freeing the device's
2859 counter */
2860 if (counter && !xorg_list_is_empty(&SysCounterList))
2861 xorg_list_del(&counter->pSysCounterInfo->entry);
2862}