This source file includes following definitions.
- perhaps_yield
- worker_thread
- test_thread_local
- main
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <config.h>
20
21 #include <threads.h>
22
23 #ifdef thread_local
24
25
26
27 #define EXPLICIT_YIELD 1
28
29
30 #define ENABLE_DEBUGGING 0
31
32
33 #define THREAD_COUNT 16
34
35
36 #define REPEAT_COUNT 50000
37
38 #include <stdint.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41
42 #if HAVE_DECL_ALARM
43 # include <signal.h>
44 # include <unistd.h>
45 #endif
46
47 #include "macros.h"
48
49 #if ENABLE_DEBUGGING
50 # define dbgprintf printf
51 #else
52 # define dbgprintf if (0) printf
53 #endif
54
55 #if EXPLICIT_YIELD
56 # define yield() thrd_yield ()
57 #else
58 # define yield()
59 #endif
60
61
62 #if defined __MVS__
63
64
65
66 # define thrd_current_pointer() (*((void **) thrd_current ().__))
67 #elif defined __sun
68
69 # define thrd_current_pointer() ((void *) (uintptr_t) thrd_current ())
70 #else
71 # define thrd_current_pointer() ((void *) thrd_current ())
72 #endif
73
74 static void
75 perhaps_yield (void)
76 {
77
78
79 if ((((unsigned int) rand () >> 3) % 4) == 0)
80 yield ();
81 }
82
83
84
85
86 #define KEYS_COUNT 4
87 static unsigned int thread_local value0;
88 static unsigned int thread_local value1;
89 static unsigned int thread_local value2;
90 static unsigned int thread_local value3;
91
92 static int
93 worker_thread (void *arg)
94 {
95 unsigned int id = (unsigned int) (uintptr_t) arg;
96 int i, j, repeat;
97 unsigned int *values[KEYS_COUNT] = { &value0, &value1, &value2, &value3 };
98
99 dbgprintf ("Worker %p started\n", thrd_current_pointer ());
100
101
102 dbgprintf ("Worker %p before first assignment\n", thrd_current_pointer ());
103 for (i = 0; i < KEYS_COUNT; i++)
104 {
105 *values[i] = (((unsigned int) rand () >> 3) % 1000000) * THREAD_COUNT + id;
106
107 if ((*values[i] % THREAD_COUNT) != id)
108 abort ();
109 }
110 dbgprintf ("Worker %p after first assignment\n", thrd_current_pointer ());
111 perhaps_yield ();
112
113
114 for (repeat = REPEAT_COUNT; repeat > 0; repeat--)
115 {
116 dbgprintf ("Worker %p doing value swapping\n", thrd_current_pointer ());
117 i = ((unsigned int) rand () >> 3) % KEYS_COUNT;
118 j = ((unsigned int) rand () >> 3) % KEYS_COUNT;
119 if (i != j)
120 {
121 unsigned int vi = *values[i];
122 unsigned int vj = *values[j];
123
124 *values[i] = vj;
125 *values[j] = vi;
126 }
127 perhaps_yield ();
128 }
129
130
131 dbgprintf ("Worker %p before final verify\n", thrd_current_pointer ());
132 for (i = 0; i < KEYS_COUNT; i++)
133 if ((*values[i] % THREAD_COUNT) != id)
134 abort ();
135 dbgprintf ("Worker %p after final verify\n", thrd_current_pointer ());
136 perhaps_yield ();
137
138 dbgprintf ("Worker %p dying.\n", thrd_current_pointer ());
139 return 0;
140 }
141
142 static void
143 test_thread_local (void)
144 {
145 int pass, i;
146
147 for (pass = 0; pass < 2; pass++)
148 {
149 thrd_t threads[THREAD_COUNT];
150
151
152 for (i = 0; i < THREAD_COUNT; i++)
153 ASSERT (thrd_create (&threads[i], worker_thread, (void *) (uintptr_t) i)
154 == thrd_success);
155
156
157 for (i = 0; i < THREAD_COUNT; i++)
158 ASSERT (thrd_join (threads[i], NULL) == thrd_success);
159 }
160 }
161
162
163
164
165 int
166 main ()
167 {
168 #if HAVE_DECL_ALARM
169
170
171 int alarm_value = 600;
172 signal (SIGALRM, SIG_DFL);
173 alarm (alarm_value);
174 #endif
175
176 printf ("Starting test_thread_local ..."); fflush (stdout);
177 test_thread_local ();
178 printf (" OK\n"); fflush (stdout);
179
180 return 0;
181 }
182
183 #else
184
185
186
187 #include <stdio.h>
188
189 int
190 main ()
191 {
192 fputs ("Skipping test: thread_local not supported\n", stderr);
193 return 77;
194 }
195
196 #endif