test/testatomic.c
changeset 5004 0c72ae7b7cb2
parent 5003 3a95a2b93eb3
child 5006 8e8876e4aec6
equal deleted inserted replaced
5003:3a95a2b93eb3 5004:0c72ae7b7cb2
     1 #include <stdio.h>
     1 #include <stdio.h>
     2 #include "SDL.h"
     2 #include "SDL.h"
       
     3 #include "SDL_assert.h"
     3 
     4 
     4 /*
     5 /*
     5   Absolutely basic tests just to see if we get the expected value
     6   Absolutely basic tests just to see if we get the expected value
     6   after calling each function.
     7   after calling each function.
     7 */
     8 */
     8 
     9 
       
    10 static
     9 char *
    11 char *
    10 tf(SDL_bool tf)
    12 tf(SDL_bool tf)
    11 {
    13 {
    12     static char *t = "TRUE";
    14     static char *t = "TRUE";
    13     static char *f = "FALSE";
    15     static char *f = "FALSE";
    18     }
    20     }
    19 
    21 
    20     return f;
    22     return f;
    21 }
    23 }
    22 
    24 
    23 int
    25 static
    24 main(int argc, char *argv[])
    26 void RunBasicTest()
    25 {
    27 {
    26     int value;
    28     int value;
    27     SDL_SpinLock lock = 0;
    29     SDL_SpinLock lock = 0;
    28 
    30 
    29     SDL_bool tfret = SDL_FALSE;
    31     SDL_bool tfret = SDL_FALSE;
    56     printf("AtomicDecRef()       tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
    58     printf("AtomicDecRef()       tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
    57     tfret = (SDL_AtomicDecRef(&v) == SDL_TRUE);
    59     tfret = (SDL_AtomicDecRef(&v) == SDL_TRUE);
    58     printf("AtomicDecRef()       tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
    60     printf("AtomicDecRef()       tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
    59 
    61 
    60     SDL_AtomicSet(&v, 10);
    62     SDL_AtomicSet(&v, 10);
    61     tfret = (SDL_AtomicCAS(&v, 0, 20) != 0);
    63     tfret = (SDL_AtomicCAS(&v, 0, 20) == SDL_FALSE);
    62     printf("AtomicCAS()          tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
    64     printf("AtomicCAS()          tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
    63     value = SDL_AtomicGet(&v);
    65     value = SDL_AtomicGet(&v);
    64     tfret = (SDL_AtomicCAS(&v, value, 20) == value);
    66     tfret = (SDL_AtomicCAS(&v, value, 20) == SDL_TRUE);
    65     printf("AtomicCAS()          tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
    67     printf("AtomicCAS()          tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
    66 
    68 }
       
    69 
       
    70 /* Atomic operation test, adapted from code by Michael Davidsaver at:
       
    71     http://bazaar.launchpad.net/~mdavidsaver/epics-base/atomic/revision/12105#src/libCom/test/epicsAtomicTest.c
       
    72 */
       
    73 
       
    74 /* Tests semantics of atomic operations.  Also a stress test
       
    75  * to see if they are really atomic.
       
    76  *
       
    77  * Serveral threads adding to the same variable.
       
    78  * at the end the value is compared with the expected
       
    79  * and with a non-atomic counter.
       
    80  */
       
    81  
       
    82 /* Number of concurrent incrementers */
       
    83 #define NThreads 2
       
    84 #define CountInc 100
       
    85 #define VALBITS (sizeof(atomicValue)*8)
       
    86  
       
    87 #define atomicValue int
       
    88 #define CountTo ((atomicValue)((unsigned int)(1<<(VALBITS-1))-1))
       
    89 #define NInter (CountTo/CountInc/NThreads)
       
    90 #define Expect (CountTo-NInter*CountInc*NThreads)
       
    91  
       
    92 SDL_COMPILE_TIME_ASSERT(size, CountTo>0); /* check for rollover */
       
    93  
       
    94 static SDL_atomic_t good = { 42 };
       
    95  
       
    96 static atomicValue bad = 42;
       
    97  
       
    98 static SDL_atomic_t threadsRunning;
       
    99 
       
   100 static SDL_sem *threadDone;
       
   101  
       
   102 static
       
   103 int adder(void* junk)
       
   104 {
       
   105     unsigned long N=NInter;
       
   106     printf("Thread subtracting %d %lu times\n",CountInc,N);
       
   107     while (N--) {
       
   108         SDL_AtomicAdd(&good, -CountInc);
       
   109         bad-=CountInc;
       
   110     }
       
   111     SDL_AtomicAdd(&threadsRunning, -1);
       
   112     SDL_SemPost(threadDone);
    67     return 0;
   113     return 0;
    68 }
   114 }
       
   115  
       
   116 static
       
   117 void runAdder(void)
       
   118 {
       
   119     Uint32 start, end;
       
   120     int T=NThreads;
       
   121  
       
   122     start = SDL_GetTicks();
       
   123  
       
   124     threadDone = SDL_CreateSemaphore(0);
       
   125 
       
   126     SDL_AtomicSet(&threadsRunning, NThreads);
       
   127 
       
   128     while (T--)
       
   129         SDL_CreateThread(adder, NULL);
       
   130  
       
   131     while (SDL_AtomicGet(&threadsRunning) > 0)
       
   132         SDL_SemWait(threadDone);
       
   133  
       
   134     SDL_DestroySemaphore(threadDone);
       
   135 
       
   136     end = SDL_GetTicks();
       
   137  
       
   138     printf("Finished in %f sec\n", (end - start) / 1000.f);
       
   139 }
       
   140  
       
   141 static
       
   142 void RunEpicTest()
       
   143 {
       
   144     int b;
       
   145     atomicValue v;
       
   146  
       
   147     printf("\nepic test---------------------------------------\n\n");
       
   148 
       
   149     printf("Size asserted to be >= 32-bit\n");
       
   150     SDL_assert(sizeof(atomicValue)>=4);
       
   151  
       
   152     printf("Check static initializer\n");
       
   153     v=SDL_AtomicGet(&good);
       
   154     SDL_assert(v==42);
       
   155  
       
   156     SDL_assert(bad==42);
       
   157  
       
   158     printf("Test negative values\n");
       
   159     SDL_AtomicSet(&good, -5);
       
   160     v=SDL_AtomicGet(&good);
       
   161     SDL_assert(v==-5);
       
   162  
       
   163     printf("Verify maximum value\n");
       
   164     SDL_AtomicSet(&good, CountTo);
       
   165     v=SDL_AtomicGet(&good);
       
   166     SDL_assert(v==CountTo);
       
   167  
       
   168     printf("Test compare and exchange\n");
       
   169  
       
   170     b=SDL_AtomicCAS(&good, 500, 43);
       
   171     SDL_assert(!b); /* no swap since CountTo!=500 */
       
   172     v=SDL_AtomicGet(&good);
       
   173     SDL_assert(v==CountTo); /* ensure no swap */
       
   174  
       
   175     b=SDL_AtomicCAS(&good, CountTo, 44);
       
   176     SDL_assert(!!b); /* will swap */
       
   177     v=SDL_AtomicGet(&good);
       
   178     SDL_assert(v==44);
       
   179  
       
   180     printf("Test Add\n");
       
   181  
       
   182     v=SDL_AtomicAdd(&good, 1);
       
   183     SDL_assert(v==44);
       
   184     v=SDL_AtomicGet(&good);
       
   185     SDL_assert(v==45);
       
   186  
       
   187     v=SDL_AtomicAdd(&good, 10);
       
   188     SDL_assert(v==45);
       
   189     v=SDL_AtomicGet(&good);
       
   190     SDL_assert(v==55);
       
   191  
       
   192     printf("Test Add (Negative values)\n");
       
   193  
       
   194     v=SDL_AtomicAdd(&good, -20);
       
   195     SDL_assert(v==55);
       
   196     v=SDL_AtomicGet(&good);
       
   197     SDL_assert(v==35);
       
   198  
       
   199     v=SDL_AtomicAdd(&good, -50); /* crossing zero down */
       
   200     SDL_assert(v==35);
       
   201     v=SDL_AtomicGet(&good);
       
   202     SDL_assert(v==-15);
       
   203  
       
   204     v=SDL_AtomicAdd(&good, 30); /* crossing zero up */
       
   205     SDL_assert(v==-15);
       
   206     v=SDL_AtomicGet(&good);
       
   207     SDL_assert(v==15);
       
   208  
       
   209     printf("Reset before count down test\n");
       
   210     SDL_AtomicSet(&good, CountTo);
       
   211     v=SDL_AtomicGet(&good);
       
   212     SDL_assert(v==CountTo);
       
   213  
       
   214     bad=CountTo;
       
   215     SDL_assert(bad==CountTo);
       
   216  
       
   217     printf("Counting down from %d, Expect %d remaining\n",CountTo,Expect);
       
   218     runAdder();
       
   219  
       
   220     v=SDL_AtomicGet(&good);
       
   221     printf("Atomic %d Non-Atomic %d\n",v,bad);
       
   222     SDL_assert(v==Expect);
       
   223     SDL_assert(bad!=Expect);
       
   224 }
       
   225 
       
   226 int
       
   227 main(int argc, char *argv[])
       
   228 {
       
   229     RunBasicTest();
       
   230     RunEpicTest();
       
   231     return 0;
       
   232 }