Home | History | Annotate | Download | only in tests
      1 /* Test data race detection between floating point variables. */
      2 
      3 
      4 #include <assert.h>
      5 #include <stdio.h>     /* printf() */
      6 #include <pthread.h>
      7 #include <unistd.h>    /* sleep() */
      8 
      9 
     10 /* Local functions declarations. */
     11 
     12 static void* thread_func(void*);
     13 
     14 
     15 /* Local variables. */
     16 
     17 /* s_mutex protects s_d3. */
     18 static pthread_mutex_t s_mutex;
     19 
     20 static double s_d1; /* accessed before thread creation and in the created */
     21                     /* thread (not a race). */
     22 static double s_d2; /* accessed in the created thread and after the join */
     23                     /* (not a race). */
     24 static double s_d3; /* accessed simultaneously from both threads (race). */
     25 static int    s_debug     = 0;
     26 static int    s_do_printf = 0;
     27 static int    s_use_mutex = 0;
     28 
     29 
     30 /* Function definitions. */
     31 
     32 int main(int argc, char** argv)
     33 {
     34   int optchar;
     35   pthread_t threadid;
     36 
     37   while ((optchar = getopt(argc, argv, "dmp")) != EOF)
     38   {
     39     switch (optchar)
     40     {
     41     case 'd':
     42       s_debug = 1;
     43       break;
     44     case 'm':
     45       s_use_mutex = 1;
     46       break;
     47     case 'p':
     48       s_do_printf = 1;
     49       break;
     50     default:
     51       assert(0);
     52     }
     53   }
     54 
     55   pthread_mutex_init(&s_mutex, 0);
     56 
     57   /*
     58    * Switch to line-buffered mode, such that timing information can be
     59    * obtained for each printf() call with strace.
     60    */
     61   setlinebuf(stdout);
     62 
     63   if (s_debug)
     64   {
     65     printf("&s_d1 = %p; &s_d2 = %p; &s_d3 = %p\n", &s_d1, &s_d2, &s_d3);
     66   }
     67 
     68   s_d1 = 1;
     69   s_d3 = 3;
     70 
     71   pthread_create(&threadid, 0, thread_func, 0);
     72 
     73   sleep(1); /* Wait until thread_func() finished. */
     74 
     75   {
     76     if (s_use_mutex) pthread_mutex_lock(&s_mutex);
     77     s_d3++;
     78     if (s_use_mutex) pthread_mutex_unlock(&s_mutex);
     79   }
     80 
     81   /* Wait until the thread finished. */
     82   pthread_join(threadid, 0);
     83   if (s_do_printf) printf("s_d2 = %g (should be 2)\n", s_d2);
     84   if (s_do_printf) printf("s_d3 = %g (should be 5)\n", s_d3);
     85 
     86   pthread_mutex_destroy(&s_mutex);
     87 
     88   return 0;
     89 }
     90 
     91 static void* thread_func(void* thread_arg)
     92 {
     93   if (s_do_printf)
     94   {
     95     printf("s_d1 = %g (should be 1)\n", s_d1);
     96   }
     97   s_d2 = 2;
     98   {
     99     if (s_use_mutex) pthread_mutex_lock(&s_mutex);
    100     s_d3++;
    101     if (s_use_mutex) pthread_mutex_unlock(&s_mutex);
    102   }
    103   return 0;
    104 }
    105