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
12static void* thread_func(void*);
13
14
15/* Local variables. */
16
17/* s_mutex protects s_d3. */
18static pthread_mutex_t s_mutex;
19
20static double s_d1; /* accessed before thread creation and in the created */
21                    /* thread (not a race). */
22static double s_d2; /* accessed in the created thread and after the join */
23                    /* (not a race). */
24static double s_d3; /* accessed simultaneously from both threads (race). */
25static int    s_debug     = 0;
26static int    s_do_printf = 0;
27static int    s_use_mutex = 0;
28
29
30/* Function definitions. */
31
32int 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
91static 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