static int adder(void* junk) { unsigned long N=NInter; printf("Thread subtracting %d %lu times\n",CountInc,N); while (N--) { SDL_AtomicAdd(&good, -CountInc); bad-=CountInc; } SDL_AtomicAdd(&threadsRunning, -1); SDL_SemPost(threadDone); return 0; }
static int FIFO_Writer(void* _data) { WriterData *data = (WriterData *)_data; SDL_EventQueue *queue = data->queue; int index = data->index; int i; SDL_Event event; event.type = SDL_USEREVENT; event.user.windowID = 0; event.user.code = 0; event.user.data1 = data; event.user.data2 = NULL; if (data->lock_free) { for (i = 0; i < EVENTS_PER_WRITER; ++i) { event.user.code = i; while (!EnqueueEvent_LockFree(queue, &event)) { ++data->waits; SDL_Delay(0); } } } else { for (i = 0; i < EVENTS_PER_WRITER; ++i) { event.user.code = i; while (!EnqueueEvent_Mutex(queue, &event)) { ++data->waits; SDL_Delay(0); } } } SDL_AtomicAdd(&writersRunning, -1); SDL_SemPost(writersDone); return 0; }
// do the next job available in the ring buffer, returns if anything was actually done bool jrq_ProcessNext( JobRingQueue* queue ) { int idx = queue->tail.value; if( idx != queue->head.value ) { if( SDL_AtomicCAS( &( queue->tail ), idx, ( idx + 1 ) % queue->size ) ) { SDL_AtomicAdd( &( queue->busy ), 1 ); if( queue->ringBuffer[idx].process != NULL ) queue->ringBuffer[idx].process( queue->ringBuffer[idx].data ); queue->ringBuffer[idx].process = NULL; // invalidate the job SDL_AtomicAdd( &( queue->busy ), -1 ); return true; } } return false; }
static void RunBasicTest() { int value; SDL_SpinLock lock = 0; SDL_atomic_t v; SDL_bool tfret = SDL_FALSE; printf("\nspin lock---------------------------------------\n\n"); SDL_AtomicLock(&lock); printf("AtomicLock lock=%d\n", lock); SDL_AtomicUnlock(&lock); printf("AtomicUnlock lock=%d\n", lock); printf("\natomic -----------------------------------------\n\n"); SDL_AtomicSet(&v, 0); tfret = SDL_AtomicSet(&v, 10) == 0; printf("AtomicSet(10) tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v)); tfret = SDL_AtomicAdd(&v, 10) == 10; printf("AtomicAdd(10) tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v)); SDL_AtomicSet(&v, 0); SDL_AtomicIncRef(&v); tfret = (SDL_AtomicGet(&v) == 1); printf("AtomicIncRef() tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v)); SDL_AtomicIncRef(&v); tfret = (SDL_AtomicGet(&v) == 2); printf("AtomicIncRef() tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v)); tfret = (SDL_AtomicDecRef(&v) == SDL_FALSE); printf("AtomicDecRef() tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v)); tfret = (SDL_AtomicDecRef(&v) == SDL_TRUE); printf("AtomicDecRef() tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v)); SDL_AtomicSet(&v, 10); tfret = (SDL_AtomicCAS(&v, 0, 20) == SDL_FALSE); printf("AtomicCAS() tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v)); value = SDL_AtomicGet(&v); tfret = (SDL_AtomicCAS(&v, value, 20) == SDL_TRUE); printf("AtomicCAS() tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v)); }
static int FIFO_Reader(void* _data) { ReaderData *data = (ReaderData *)_data; SDL_EventQueue *queue = data->queue; SDL_Event event; if (data->lock_free) { for ( ; ; ) { if (DequeueEvent_LockFree(queue, &event)) { WriterData *writer = (WriterData*)event.user.data1; ++data->counters[writer->index]; } else if (queue->active) { ++data->waits; SDL_Delay(0); } else { /* We drained the queue, we're done! */ break; } } } else { for ( ; ; ) { if (DequeueEvent_Mutex(queue, &event)) { WriterData *writer = (WriterData*)event.user.data1; ++data->counters[writer->index]; } else if (queue->active) { ++data->waits; SDL_Delay(0); } else { /* We drained the queue, we're done! */ break; } } } SDL_AtomicAdd(&readersRunning, -1); SDL_SemPost(readersDone); return 0; }
/* * Sys_Atomic_Add */ int Sys_Atomic_Add( volatile int *value, int add, qmutex_t *mutex ) { return SDL_AtomicAdd( ( SDL_atomic_t * )value, add ) + add; }
static void RunEpicTest() { int b; atomicValue v; printf("\nepic test---------------------------------------\n\n"); printf("Size asserted to be >= 32-bit\n"); SDL_assert(sizeof(atomicValue)>=4); printf("Check static initializer\n"); v=SDL_AtomicGet(&good); SDL_assert(v==42); SDL_assert(bad==42); printf("Test negative values\n"); SDL_AtomicSet(&good, -5); v=SDL_AtomicGet(&good); SDL_assert(v==-5); printf("Verify maximum value\n"); SDL_AtomicSet(&good, CountTo); v=SDL_AtomicGet(&good); SDL_assert(v==CountTo); printf("Test compare and exchange\n"); b=SDL_AtomicCAS(&good, 500, 43); SDL_assert(!b); /* no swap since CountTo!=500 */ v=SDL_AtomicGet(&good); SDL_assert(v==CountTo); /* ensure no swap */ b=SDL_AtomicCAS(&good, CountTo, 44); SDL_assert(!!b); /* will swap */ v=SDL_AtomicGet(&good); SDL_assert(v==44); printf("Test Add\n"); v=SDL_AtomicAdd(&good, 1); SDL_assert(v==44); v=SDL_AtomicGet(&good); SDL_assert(v==45); v=SDL_AtomicAdd(&good, 10); SDL_assert(v==45); v=SDL_AtomicGet(&good); SDL_assert(v==55); printf("Test Add (Negative values)\n"); v=SDL_AtomicAdd(&good, -20); SDL_assert(v==55); v=SDL_AtomicGet(&good); SDL_assert(v==35); v=SDL_AtomicAdd(&good, -50); /* crossing zero down */ SDL_assert(v==35); v=SDL_AtomicGet(&good); SDL_assert(v==-15); v=SDL_AtomicAdd(&good, 30); /* crossing zero up */ SDL_assert(v==-15); v=SDL_AtomicGet(&good); SDL_assert(v==15); printf("Reset before count down test\n"); SDL_AtomicSet(&good, CountTo); v=SDL_AtomicGet(&good); SDL_assert(v==CountTo); bad=CountTo; SDL_assert(bad==CountTo); printf("Counting down from %d, Expect %d remaining\n",CountTo,Expect); runAdder(); v=SDL_AtomicGet(&good); printf("Atomic %d Non-Atomic %d\n",v,bad); SDL_assert(v==Expect); SDL_assert(bad!=Expect); }