• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
main(int argc,char ** argv)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 
thread_func(void * thread_arg)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