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