blob: 65d13a37fbe208687e4f7055689089a17441ce45 [file] [log] [blame]
bart55df6e72009-02-16 19:42:17 +00001/* Test data race detection between floating point variables. */
sewardjaf44c822007-11-25 14:01:38 +00002
sewardjaf44c822007-11-25 14:01:38 +00003
sewardjc68cbe32007-11-27 01:59:38 +00004#include <assert.h>
bart55df6e72009-02-16 19:42:17 +00005#include <stdio.h> /* printf() */
sewardjaf44c822007-11-25 14:01:38 +00006#include <pthread.h>
bart3ab0baf2009-07-21 11:12:14 +00007#include <unistd.h> /* sleep() */
bart5f57be92008-07-01 08:48:56 +00008
sewardjaf44c822007-11-25 14:01:38 +00009
bart55df6e72009-02-16 19:42:17 +000010/* Local functions declarations. */
sewardjaf44c822007-11-25 14:01:38 +000011
12static void* thread_func(void*);
13
sewardjaf44c822007-11-25 14:01:38 +000014
bart55df6e72009-02-16 19:42:17 +000015/* Local variables. */
16
17/* s_mutex protects s_d3. */
sewardjaf44c822007-11-25 14:01:38 +000018static pthread_mutex_t s_mutex;
19
bart55df6e72009-02-16 19:42:17 +000020static 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). */
sewardjc68cbe32007-11-27 01:59:38 +000025static int s_debug = 0;
26static int s_do_printf = 0;
27static int s_use_mutex = 0;
sewardjaf44c822007-11-25 14:01:38 +000028
29
bart55df6e72009-02-16 19:42:17 +000030/* Function definitions. */
sewardjaf44c822007-11-25 14:01:38 +000031
sewardjaf44c822007-11-25 14:01:38 +000032int main(int argc, char** argv)
33{
sewardjc68cbe32007-11-27 01:59:38 +000034 int optchar;
35 pthread_t threadid;
36
sewardjaf44c822007-11-25 14:01:38 +000037 while ((optchar = getopt(argc, argv, "dmp")) != EOF)
38 {
39 switch (optchar)
40 {
41 case 'd':
sewardjc68cbe32007-11-27 01:59:38 +000042 s_debug = 1;
sewardjaf44c822007-11-25 14:01:38 +000043 break;
44 case 'm':
sewardjc68cbe32007-11-27 01:59:38 +000045 s_use_mutex = 1;
sewardjaf44c822007-11-25 14:01:38 +000046 break;
47 case 'p':
sewardjc68cbe32007-11-27 01:59:38 +000048 s_do_printf = 1;
sewardjaf44c822007-11-25 14:01:38 +000049 break;
50 default:
sewardjc68cbe32007-11-27 01:59:38 +000051 assert(0);
sewardjaf44c822007-11-25 14:01:38 +000052 }
53 }
54
55 pthread_mutex_init(&s_mutex, 0);
56
bart55df6e72009-02-16 19:42:17 +000057 /*
bart31b983d2010-02-21 14:52:59 +000058 * Switch to line-buffered mode, such that timing information can be
bart55df6e72009-02-16 19:42:17 +000059 * obtained for each printf() call with strace.
60 */
sewardjaf44c822007-11-25 14:01:38 +000061 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
sewardjaf44c822007-11-25 14:01:38 +000071 pthread_create(&threadid, 0, thread_func, 0);
sewardjaf44c822007-11-25 14:01:38 +000072
bart1061b672009-03-11 19:13:34 +000073 sleep(1); /* Wait until thread_func() finished. */
74
sewardjaf44c822007-11-25 14:01:38 +000075 {
sewardjc68cbe32007-11-27 01:59:38 +000076 if (s_use_mutex) pthread_mutex_lock(&s_mutex);
sewardjaf44c822007-11-25 14:01:38 +000077 s_d3++;
sewardjc68cbe32007-11-27 01:59:38 +000078 if (s_use_mutex) pthread_mutex_unlock(&s_mutex);
sewardjaf44c822007-11-25 14:01:38 +000079 }
80
bart55df6e72009-02-16 19:42:17 +000081 /* Wait until the thread finished. */
sewardjaf44c822007-11-25 14:01:38 +000082 pthread_join(threadid, 0);
sewardjaf44c822007-11-25 14:01:38 +000083 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
sewardjc68cbe32007-11-27 01:59:38 +000091static void* thread_func(void* thread_arg)
sewardjaf44c822007-11-25 14:01:38 +000092{
sewardjaf44c822007-11-25 14:01:38 +000093 if (s_do_printf)
94 {
95 printf("s_d1 = %g (should be 1)\n", s_d1);
96 }
97 s_d2 = 2;
98 {
sewardjc68cbe32007-11-27 01:59:38 +000099 if (s_use_mutex) pthread_mutex_lock(&s_mutex);
sewardjaf44c822007-11-25 14:01:38 +0000100 s_d3++;
sewardjc68cbe32007-11-27 01:59:38 +0000101 if (s_use_mutex) pthread_mutex_unlock(&s_mutex);
sewardjaf44c822007-11-25 14:01:38 +0000102 }
103 return 0;
104}