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