/[pcsx2_0.9.7]/trunk/3rdparty/SDL-1.3.0-5387/test/testatomic.c
ViewVC logotype

Contents of /trunk/3rdparty/SDL-1.3.0-5387/test/testatomic.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 401 - (show annotations) (download)
Fri Feb 25 17:31:09 2011 UTC (9 years, 9 months ago) by william
File MIME type: text/plain
File size: 19265 byte(s)
Auto Commited Import of: pcsx2-0.9.7-DEBUG (upstream: v0.9.7.4358 local: v0.9.7.313-latest) in ./trunk
1 #include <stdio.h>
2
3 #include "SDL.h"
4 #include "SDL_atomic.h"
5 #include "SDL_assert.h"
6 #include "SDL_cpuinfo.h"
7
8 /*
9 Absolutely basic tests just to see if we get the expected value
10 after calling each function.
11 */
12
13 static
14 char *
15 tf(SDL_bool tf)
16 {
17 static char *t = "TRUE";
18 static char *f = "FALSE";
19
20 if (tf)
21 {
22 return t;
23 }
24
25 return f;
26 }
27
28 static
29 void RunBasicTest()
30 {
31 int value;
32 SDL_SpinLock lock = 0;
33
34 SDL_atomic_t v;
35 SDL_bool tfret = SDL_FALSE;
36
37 printf("\nspin lock---------------------------------------\n\n");
38
39 SDL_AtomicLock(&lock);
40 printf("AtomicLock lock=%d\n", lock);
41 SDL_AtomicUnlock(&lock);
42 printf("AtomicUnlock lock=%d\n", lock);
43
44 printf("\natomic -----------------------------------------\n\n");
45
46 SDL_AtomicSet(&v, 0);
47 tfret = SDL_AtomicSet(&v, 10) == 0;
48 printf("AtomicSet(10) tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v));
49 tfret = SDL_AtomicAdd(&v, 10) == 10;
50 printf("AtomicAdd(10) tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v));
51
52 SDL_AtomicSet(&v, 0);
53 SDL_AtomicIncRef(&v);
54 tfret = (SDL_AtomicGet(&v) == 1);
55 printf("AtomicIncRef() tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v));
56 SDL_AtomicIncRef(&v);
57 tfret = (SDL_AtomicGet(&v) == 2);
58 printf("AtomicIncRef() tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v));
59 tfret = (SDL_AtomicDecRef(&v) == SDL_FALSE);
60 printf("AtomicDecRef() tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v));
61 tfret = (SDL_AtomicDecRef(&v) == SDL_TRUE);
62 printf("AtomicDecRef() tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v));
63
64 SDL_AtomicSet(&v, 10);
65 tfret = (SDL_AtomicCAS(&v, 0, 20) == SDL_FALSE);
66 printf("AtomicCAS() tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v));
67 value = SDL_AtomicGet(&v);
68 tfret = (SDL_AtomicCAS(&v, value, 20) == SDL_TRUE);
69 printf("AtomicCAS() tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v));
70 }
71
72 /**************************************************************************/
73 /* Atomic operation test
74 * Adapted with permission from code by Michael Davidsaver at:
75 * http://bazaar.launchpad.net/~mdavidsaver/epics-base/atomic/revision/12105#src/libCom/test/epicsAtomicTest.c
76 * Original copyright 2010 Brookhaven Science Associates as operator of Brookhaven National Lab
77 * http://www.aps.anl.gov/epics/license/open.php
78 */
79
80 /* Tests semantics of atomic operations. Also a stress test
81 * to see if they are really atomic.
82 *
83 * Serveral threads adding to the same variable.
84 * at the end the value is compared with the expected
85 * and with a non-atomic counter.
86 */
87
88 /* Number of concurrent incrementers */
89 #define NThreads 2
90 #define CountInc 100
91 #define VALBITS (sizeof(atomicValue)*8)
92
93 #define atomicValue int
94 #define CountTo ((atomicValue)((unsigned int)(1<<(VALBITS-1))-1))
95 #define NInter (CountTo/CountInc/NThreads)
96 #define Expect (CountTo-NInter*CountInc*NThreads)
97
98 SDL_COMPILE_TIME_ASSERT(size, CountTo>0); /* check for rollover */
99
100 static SDL_atomic_t good = { 42 };
101
102 static atomicValue bad = 42;
103
104 static SDL_atomic_t threadsRunning;
105
106 static SDL_sem *threadDone;
107
108 static
109 int adder(void* junk)
110 {
111 unsigned long N=NInter;
112 printf("Thread subtracting %d %lu times\n",CountInc,N);
113 while (N--) {
114 SDL_AtomicAdd(&good, -CountInc);
115 bad-=CountInc;
116 }
117 SDL_AtomicAdd(&threadsRunning, -1);
118 SDL_SemPost(threadDone);
119 return 0;
120 }
121
122 static
123 void runAdder(void)
124 {
125 Uint32 start, end;
126 int T=NThreads;
127
128 start = SDL_GetTicks();
129
130 threadDone = SDL_CreateSemaphore(0);
131
132 SDL_AtomicSet(&threadsRunning, NThreads);
133
134 while (T--)
135 SDL_CreateThread(adder, NULL);
136
137 while (SDL_AtomicGet(&threadsRunning) > 0)
138 SDL_SemWait(threadDone);
139
140 SDL_DestroySemaphore(threadDone);
141
142 end = SDL_GetTicks();
143
144 printf("Finished in %f sec\n", (end - start) / 1000.f);
145 }
146
147 static
148 void RunEpicTest()
149 {
150 int b;
151 atomicValue v;
152
153 printf("\nepic test---------------------------------------\n\n");
154
155 printf("Size asserted to be >= 32-bit\n");
156 SDL_assert(sizeof(atomicValue)>=4);
157
158 printf("Check static initializer\n");
159 v=SDL_AtomicGet(&good);
160 SDL_assert(v==42);
161
162 SDL_assert(bad==42);
163
164 printf("Test negative values\n");
165 SDL_AtomicSet(&good, -5);
166 v=SDL_AtomicGet(&good);
167 SDL_assert(v==-5);
168
169 printf("Verify maximum value\n");
170 SDL_AtomicSet(&good, CountTo);
171 v=SDL_AtomicGet(&good);
172 SDL_assert(v==CountTo);
173
174 printf("Test compare and exchange\n");
175
176 b=SDL_AtomicCAS(&good, 500, 43);
177 SDL_assert(!b); /* no swap since CountTo!=500 */
178 v=SDL_AtomicGet(&good);
179 SDL_assert(v==CountTo); /* ensure no swap */
180
181 b=SDL_AtomicCAS(&good, CountTo, 44);
182 SDL_assert(!!b); /* will swap */
183 v=SDL_AtomicGet(&good);
184 SDL_assert(v==44);
185
186 printf("Test Add\n");
187
188 v=SDL_AtomicAdd(&good, 1);
189 SDL_assert(v==44);
190 v=SDL_AtomicGet(&good);
191 SDL_assert(v==45);
192
193 v=SDL_AtomicAdd(&good, 10);
194 SDL_assert(v==45);
195 v=SDL_AtomicGet(&good);
196 SDL_assert(v==55);
197
198 printf("Test Add (Negative values)\n");
199
200 v=SDL_AtomicAdd(&good, -20);
201 SDL_assert(v==55);
202 v=SDL_AtomicGet(&good);
203 SDL_assert(v==35);
204
205 v=SDL_AtomicAdd(&good, -50); /* crossing zero down */
206 SDL_assert(v==35);
207 v=SDL_AtomicGet(&good);
208 SDL_assert(v==-15);
209
210 v=SDL_AtomicAdd(&good, 30); /* crossing zero up */
211 SDL_assert(v==-15);
212 v=SDL_AtomicGet(&good);
213 SDL_assert(v==15);
214
215 printf("Reset before count down test\n");
216 SDL_AtomicSet(&good, CountTo);
217 v=SDL_AtomicGet(&good);
218 SDL_assert(v==CountTo);
219
220 bad=CountTo;
221 SDL_assert(bad==CountTo);
222
223 printf("Counting down from %d, Expect %d remaining\n",CountTo,Expect);
224 runAdder();
225
226 v=SDL_AtomicGet(&good);
227 printf("Atomic %d Non-Atomic %d\n",v,bad);
228 SDL_assert(v==Expect);
229 SDL_assert(bad!=Expect);
230 }
231
232 /* End atomic operation test */
233 /**************************************************************************/
234
235 /**************************************************************************/
236 /* Lock-free FIFO test */
237
238 /* This is useful to test the impact of another thread locking the queue
239 entirely for heavy-weight manipulation.
240 */
241 #define TEST_SPINLOCK_FIFO
242
243 #define NUM_READERS 4
244 #define NUM_WRITERS 4
245 #define EVENTS_PER_WRITER 1000000
246
247 /* The number of entries must be a power of 2 */
248 #define MAX_ENTRIES 256
249 #define WRAP_MASK (MAX_ENTRIES-1)
250
251 typedef struct
252 {
253 SDL_atomic_t sequence;
254 SDL_Event event;
255 } SDL_EventQueueEntry;
256
257 typedef struct
258 {
259 SDL_EventQueueEntry entries[MAX_ENTRIES];
260
261 char cache_pad1[SDL_CACHELINE_SIZE-((sizeof(SDL_EventQueueEntry)*MAX_ENTRIES)%SDL_CACHELINE_SIZE)];
262
263 SDL_atomic_t enqueue_pos;
264
265 char cache_pad2[SDL_CACHELINE_SIZE-sizeof(SDL_atomic_t)];
266
267 SDL_atomic_t dequeue_pos;
268
269 char cache_pad3[SDL_CACHELINE_SIZE-sizeof(SDL_atomic_t)];
270
271 #ifdef TEST_SPINLOCK_FIFO
272 SDL_SpinLock lock;
273 SDL_atomic_t rwcount;
274 SDL_atomic_t watcher;
275
276 char cache_pad4[SDL_CACHELINE_SIZE-sizeof(SDL_SpinLock)-2*sizeof(SDL_atomic_t)];
277 #endif
278
279 volatile SDL_bool active;
280
281 /* Only needed for the mutex test */
282 SDL_mutex *mutex;
283
284 } SDL_EventQueue;
285
286 static void InitEventQueue(SDL_EventQueue *queue)
287 {
288 int i;
289
290 for (i = 0; i < MAX_ENTRIES; ++i) {
291 SDL_AtomicSet(&queue->entries[i].sequence, i);
292 }
293 SDL_AtomicSet(&queue->enqueue_pos, 0);
294 SDL_AtomicSet(&queue->dequeue_pos, 0);
295 #ifdef TEST_SPINLOCK_FIFO
296 queue->lock = 0;
297 SDL_AtomicSet(&queue->rwcount, 0);
298 #endif
299 queue->active = SDL_TRUE;
300 }
301
302 static SDL_bool EnqueueEvent_LockFree(SDL_EventQueue *queue, const SDL_Event *event)
303 {
304 SDL_EventQueueEntry *entry;
305 unsigned queue_pos;
306 unsigned entry_seq;
307 int delta;
308 SDL_bool status;
309
310 #ifdef TEST_SPINLOCK_FIFO
311 /* This is a gate so an external thread can lock the queue */
312 SDL_AtomicLock(&queue->lock);
313 SDL_assert(SDL_AtomicGet(&queue->watcher) == 0);
314 SDL_AtomicIncRef(&queue->rwcount);
315 SDL_AtomicUnlock(&queue->lock);
316 #endif
317
318 queue_pos = (unsigned)SDL_AtomicGet(&queue->enqueue_pos);
319 for ( ; ; ) {
320 entry = &queue->entries[queue_pos & WRAP_MASK];
321 entry_seq = (unsigned)SDL_AtomicGet(&entry->sequence);
322
323 delta = (int)(entry_seq - queue_pos);
324 if (delta == 0) {
325 /* The entry and the queue position match, try to increment the queue position */
326 if (SDL_AtomicCAS(&queue->enqueue_pos, (int)queue_pos, (int)(queue_pos+1))) {
327 /* We own the object, fill it! */
328 entry->event = *event;
329 SDL_AtomicSet(&entry->sequence, (int)(queue_pos + 1));
330 status = SDL_TRUE;
331 break;
332 }
333 } else if (delta < 0) {
334 /* We ran into an old queue entry, which means it still needs to be dequeued */
335 status = SDL_FALSE;
336 break;
337 } else {
338 /* We ran into a new queue entry, get the new queue position */
339 queue_pos = (unsigned)SDL_AtomicGet(&queue->enqueue_pos);
340 }
341 }
342
343 #ifdef TEST_SPINLOCK_FIFO
344 SDL_AtomicDecRef(&queue->rwcount);
345 #endif
346 return status;
347 }
348
349 static SDL_bool DequeueEvent_LockFree(SDL_EventQueue *queue, SDL_Event *event)
350 {
351 SDL_EventQueueEntry *entry;
352 unsigned queue_pos;
353 unsigned entry_seq;
354 int delta;
355 SDL_bool status;
356
357 #ifdef TEST_SPINLOCK_FIFO
358 /* This is a gate so an external thread can lock the queue */
359 SDL_AtomicLock(&queue->lock);
360 SDL_assert(SDL_AtomicGet(&queue->watcher) == 0);
361 SDL_AtomicIncRef(&queue->rwcount);
362 SDL_AtomicUnlock(&queue->lock);
363 #endif
364
365 queue_pos = (unsigned)SDL_AtomicGet(&queue->dequeue_pos);
366 for ( ; ; ) {
367 entry = &queue->entries[queue_pos & WRAP_MASK];
368 entry_seq = (unsigned)SDL_AtomicGet(&entry->sequence);
369
370 delta = (int)(entry_seq - (queue_pos + 1));
371 if (delta == 0) {
372 /* The entry and the queue position match, try to increment the queue position */
373 if (SDL_AtomicCAS(&queue->dequeue_pos, (int)queue_pos, (int)(queue_pos+1))) {
374 /* We own the object, fill it! */
375 *event = entry->event;
376 SDL_AtomicSet(&entry->sequence, (int)(queue_pos+MAX_ENTRIES));
377 status = SDL_TRUE;
378 break;
379 }
380 } else if (delta < 0) {
381 /* We ran into an old queue entry, which means we've hit empty */
382 status = SDL_FALSE;
383 break;
384 } else {
385 /* We ran into a new queue entry, get the new queue position */
386 queue_pos = (unsigned)SDL_AtomicGet(&queue->dequeue_pos);
387 }
388 }
389
390 #ifdef TEST_SPINLOCK_FIFO
391 SDL_AtomicDecRef(&queue->rwcount);
392 #endif
393 return status;
394 }
395
396 static SDL_bool EnqueueEvent_Mutex(SDL_EventQueue *queue, const SDL_Event *event)
397 {
398 SDL_EventQueueEntry *entry;
399 unsigned queue_pos;
400 unsigned entry_seq;
401 int delta;
402 SDL_bool status = SDL_FALSE;
403
404 SDL_mutexP(queue->mutex);
405
406 queue_pos = (unsigned)queue->enqueue_pos.value;
407 entry = &queue->entries[queue_pos & WRAP_MASK];
408 entry_seq = (unsigned)entry->sequence.value;
409
410 delta = (int)(entry_seq - queue_pos);
411 if (delta == 0) {
412 ++queue->enqueue_pos.value;
413
414 /* We own the object, fill it! */
415 entry->event = *event;
416 entry->sequence.value = (int)(queue_pos + 1);
417 status = SDL_TRUE;
418 } else if (delta < 0) {
419 /* We ran into an old queue entry, which means it still needs to be dequeued */
420 } else {
421 printf("ERROR: mutex failed!\n");
422 }
423
424 SDL_mutexV(queue->mutex);
425
426 return status;
427 }
428
429 static SDL_bool DequeueEvent_Mutex(SDL_EventQueue *queue, SDL_Event *event)
430 {
431 SDL_EventQueueEntry *entry;
432 unsigned queue_pos;
433 unsigned entry_seq;
434 int delta;
435 SDL_bool status = SDL_FALSE;
436
437 SDL_mutexP(queue->mutex);
438
439 queue_pos = (unsigned)queue->dequeue_pos.value;
440 entry = &queue->entries[queue_pos & WRAP_MASK];
441 entry_seq = (unsigned)entry->sequence.value;
442
443 delta = (int)(entry_seq - (queue_pos + 1));
444 if (delta == 0) {
445 ++queue->dequeue_pos.value;
446
447 /* We own the object, fill it! */
448 *event = entry->event;
449 entry->sequence.value = (int)(queue_pos + MAX_ENTRIES);
450 status = SDL_TRUE;
451 } else if (delta < 0) {
452 /* We ran into an old queue entry, which means we've hit empty */
453 } else {
454 printf("ERROR: mutex failed!\n");
455 }
456
457 SDL_mutexV(queue->mutex);
458
459 return status;
460 }
461
462 static SDL_sem *writersDone;
463 static SDL_sem *readersDone;
464 static SDL_atomic_t writersRunning;
465 static SDL_atomic_t readersRunning;
466
467 typedef struct
468 {
469 SDL_EventQueue *queue;
470 int index;
471 char padding1[SDL_CACHELINE_SIZE-(sizeof(SDL_EventQueue*)+sizeof(int))%SDL_CACHELINE_SIZE];
472 int waits;
473 SDL_bool lock_free;
474 char padding2[SDL_CACHELINE_SIZE-sizeof(int)-sizeof(SDL_bool)];
475 } WriterData;
476
477 typedef struct
478 {
479 SDL_EventQueue *queue;
480 int counters[NUM_WRITERS];
481 int waits;
482 SDL_bool lock_free;
483 char padding[SDL_CACHELINE_SIZE-(sizeof(SDL_EventQueue*)+sizeof(int)*NUM_WRITERS+sizeof(int)+sizeof(SDL_bool))%SDL_CACHELINE_SIZE];
484 } ReaderData;
485
486 static int FIFO_Writer(void* _data)
487 {
488 WriterData *data = (WriterData *)_data;
489 SDL_EventQueue *queue = data->queue;
490 int index = data->index;
491 int i;
492 SDL_Event event;
493
494 event.type = SDL_USEREVENT;
495 event.user.windowID = 0;
496 event.user.code = 0;
497 event.user.data1 = data;
498 event.user.data2 = NULL;
499
500 if (data->lock_free) {
501 for (i = 0; i < EVENTS_PER_WRITER; ++i) {
502 event.user.code = i;
503 while (!EnqueueEvent_LockFree(queue, &event)) {
504 ++data->waits;
505 SDL_Delay(0);
506 }
507 }
508 } else {
509 for (i = 0; i < EVENTS_PER_WRITER; ++i) {
510 event.user.code = i;
511 while (!EnqueueEvent_Mutex(queue, &event)) {
512 ++data->waits;
513 SDL_Delay(0);
514 }
515 }
516 }
517 SDL_AtomicAdd(&writersRunning, -1);
518 SDL_SemPost(writersDone);
519 return 0;
520 }
521
522 static int FIFO_Reader(void* _data)
523 {
524 ReaderData *data = (ReaderData *)_data;
525 SDL_EventQueue *queue = data->queue;
526 SDL_Event event;
527
528 if (data->lock_free) {
529 for ( ; ; ) {
530 if (DequeueEvent_LockFree(queue, &event)) {
531 WriterData *writer = (WriterData*)event.user.data1;
532 ++data->counters[writer->index];
533 } else if (queue->active) {
534 ++data->waits;
535 SDL_Delay(0);
536 } else {
537 /* We drained the queue, we're done! */
538 break;
539 }
540 }
541 } else {
542 for ( ; ; ) {
543 if (DequeueEvent_Mutex(queue, &event)) {
544 WriterData *writer = (WriterData*)event.user.data1;
545 ++data->counters[writer->index];
546 } else if (queue->active) {
547 ++data->waits;
548 SDL_Delay(0);
549 } else {
550 /* We drained the queue, we're done! */
551 break;
552 }
553 }
554 }
555 SDL_AtomicAdd(&readersRunning, -1);
556 SDL_SemPost(readersDone);
557 return 0;
558 }
559
560 #ifdef TEST_SPINLOCK_FIFO
561 /* This thread periodically locks the queue for no particular reason */
562 static int FIFO_Watcher(void* _data)
563 {
564 SDL_EventQueue *queue = (SDL_EventQueue *)_data;
565
566 while (queue->active) {
567 SDL_AtomicLock(&queue->lock);
568 SDL_AtomicIncRef(&queue->watcher);
569 while (SDL_AtomicGet(&queue->rwcount) > 0) {
570 SDL_Delay(0);
571 }
572 /* Do queue manipulation here... */
573 SDL_AtomicDecRef(&queue->watcher);
574 SDL_AtomicUnlock(&queue->lock);
575
576 /* Wait a bit... */
577 SDL_Delay(1);
578 }
579 return 0;
580 }
581 #endif /* TEST_SPINLOCK_FIFO */
582
583 static void RunFIFOTest(SDL_bool lock_free)
584 {
585 SDL_EventQueue queue;
586 WriterData writerData[NUM_WRITERS];
587 ReaderData readerData[NUM_READERS];
588 Uint32 start, end;
589 int i, j;
590 int grand_total;
591
592 printf("\nFIFO test---------------------------------------\n\n");
593 printf("Mode: %s\n", lock_free ? "LockFree" : "Mutex");
594
595 readersDone = SDL_CreateSemaphore(0);
596 writersDone = SDL_CreateSemaphore(0);
597
598 SDL_memset(&queue, 0xff, sizeof(queue));
599
600 InitEventQueue(&queue);
601 if (!lock_free) {
602 queue.mutex = SDL_CreateMutex();
603 }
604
605 start = SDL_GetTicks();
606
607 #ifdef TEST_SPINLOCK_FIFO
608 /* Start a monitoring thread */
609 if (lock_free) {
610 SDL_CreateThread(FIFO_Watcher, &queue);
611 }
612 #endif
613
614 /* Start the readers first */
615 printf("Starting %d readers\n", NUM_READERS);
616 SDL_zero(readerData);
617 SDL_AtomicSet(&readersRunning, NUM_READERS);
618 for (i = 0; i < NUM_READERS; ++i) {
619 readerData[i].queue = &queue;
620 readerData[i].lock_free = lock_free;
621 SDL_CreateThread(FIFO_Reader, &readerData[i]);
622 }
623
624 /* Start up the writers */
625 printf("Starting %d writers\n", NUM_WRITERS);
626 SDL_zero(writerData);
627 SDL_AtomicSet(&writersRunning, NUM_WRITERS);
628 for (i = 0; i < NUM_WRITERS; ++i) {
629 writerData[i].queue = &queue;
630 writerData[i].index = i;
631 writerData[i].lock_free = lock_free;
632 SDL_CreateThread(FIFO_Writer, &writerData[i]);
633 }
634
635 /* Wait for the writers */
636 while (SDL_AtomicGet(&writersRunning) > 0) {
637 SDL_SemWait(writersDone);
638 }
639
640 /* Shut down the queue so readers exit */
641 queue.active = SDL_FALSE;
642
643 /* Wait for the readers */
644 while (SDL_AtomicGet(&readersRunning) > 0) {
645 SDL_SemWait(readersDone);
646 }
647
648 end = SDL_GetTicks();
649
650 SDL_DestroySemaphore(readersDone);
651 SDL_DestroySemaphore(writersDone);
652
653 if (!lock_free) {
654 SDL_DestroyMutex(queue.mutex);
655 }
656
657 printf("Finished in %f sec\n", (end - start) / 1000.f);
658
659 printf("\n");
660 for (i = 0; i < NUM_WRITERS; ++i) {
661 printf("Writer %d wrote %d events, had %d waits\n", i, EVENTS_PER_WRITER, writerData[i].waits);
662 }
663 printf("Writers wrote %d total events\n", NUM_WRITERS*EVENTS_PER_WRITER);
664
665 /* Print a breakdown of which readers read messages from which writer */
666 printf("\n");
667 grand_total = 0;
668 for (i = 0; i < NUM_READERS; ++i) {
669 int total = 0;
670 for (j = 0; j < NUM_WRITERS; ++j) {
671 total += readerData[i].counters[j];
672 }
673 grand_total += total;
674 printf("Reader %d read %d events, had %d waits\n", i, total, readerData[i].waits);
675 printf(" { ");
676 for (j = 0; j < NUM_WRITERS; ++j) {
677 if (j > 0) {
678 printf(", ");
679 }
680 printf("%d", readerData[i].counters[j]);
681 }
682 printf(" }\n");
683 }
684 printf("Readers read %d total events\n", grand_total);
685 }
686
687 /* End FIFO test */
688 /**************************************************************************/
689
690 int
691 main(int argc, char *argv[])
692 {
693 RunBasicTest();
694 RunEpicTest();
695 /* This test is really slow, so don't run it by default */
696 #if 0
697 RunFIFOTest(SDL_FALSE);
698 #endif
699 RunFIFOTest(SDL_TRUE);
700 return 0;
701 }
702
703 /* vi: set ts=4 sw=4 expandtab: */

  ViewVC Help
Powered by ViewVC 1.1.22