This source file includes following definitions.
- int_mutator_thread
- ptr_mutator_thread
- 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 "simple-atomic.h"
22
23 #if USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS
24
25
26
27 #define EXPLICIT_YIELD 1
28
29
30 #define THREAD_COUNT 4
31
32
33
34
35 #define REPEAT_COUNT 1000
36
37 #include "glthread/thread.h"
38 #include "glthread/yield.h"
39
40 #include "macros.h"
41
42 #if EXPLICIT_YIELD
43 # define yield() gl_thread_yield ()
44 #else
45 # define yield()
46 #endif
47
48
49 static unsigned int counter[THREAD_COUNT][5];
50
51
52 static unsigned int int_variable;
53
54 static void *
55 int_mutator_thread (void *arg)
56 {
57 int *pcounter = (int *) arg;
58 int repeat;
59
60 for (repeat = REPEAT_COUNT; repeat > 0; repeat--)
61 {
62 if (atomic_compare_and_swap (&int_variable, 0, 10) == 0)
63 pcounter[0]++;
64 yield ();
65
66 if (atomic_compare_and_swap (&int_variable, 14, 17) == 14)
67 pcounter[1]++;
68 yield ();
69
70 if (atomic_compare_and_swap (&int_variable, 20, 0) == 20)
71 pcounter[2]++;
72 yield ();
73
74 if (atomic_compare_and_swap (&int_variable, 10, 14) == 10)
75 pcounter[3]++;
76 yield ();
77
78 if (atomic_compare_and_swap (&int_variable, 17, 20) == 17)
79 pcounter[4]++;
80 yield ();
81 }
82
83 return NULL;
84 }
85
86
87 static uintptr_t ptr_variable;
88
89 static void *
90 ptr_mutator_thread (void *arg)
91 {
92 int *pcounter = (int *) arg;
93 int repeat;
94
95 for (repeat = REPEAT_COUNT; repeat > 0; repeat--)
96 {
97 if (atomic_compare_and_swap_ptr (&ptr_variable, 0, 10) == 0)
98 pcounter[0]++;
99 yield ();
100
101 if (atomic_compare_and_swap_ptr (&ptr_variable, 14, 17) == 14)
102 pcounter[1]++;
103 yield ();
104
105 if (atomic_compare_and_swap_ptr (&ptr_variable, 20, 0) == 20)
106 pcounter[2]++;
107 yield ();
108
109 if (atomic_compare_and_swap_ptr (&ptr_variable, 10, 14) == 10)
110 pcounter[3]++;
111 yield ();
112
113 if (atomic_compare_and_swap_ptr (&ptr_variable, 17, 20) == 17)
114 pcounter[4]++;
115 yield ();
116 }
117
118 return NULL;
119 }
120
121 int
122 main ()
123 {
124
125 {
126 unsigned int x[3] = { 0xDEADBEEFU, 11, 0xDEADBEEFU };
127
128 ASSERT (atomic_compare_and_swap (&x[1], 0, 17) == 11);
129 ASSERT (x[1] == 11);
130
131 ASSERT (atomic_compare_and_swap (&x[1], 4, 11) == 11);
132 ASSERT (x[1] == 11);
133
134 ASSERT (atomic_compare_and_swap (&x[1], 11, 15) == 11);
135 ASSERT (x[1] == 15);
136
137 ASSERT (x[0] == 0xDEADBEEFU);
138 ASSERT (x[2] == 0xDEADBEEFU);
139 }
140
141
142 {
143 uintptr_t v1 = ~(uintptr_t)0 / 3;
144 uintptr_t v2 = ~(uintptr_t)0 / 5 * 4;
145 uintptr_t v3 = ~(uintptr_t)0 / 7 * 3;
146 uintptr_t x[3] = { 0xDEADBEEFU, v1, 0xDEADBEEFU };
147
148 ASSERT (atomic_compare_and_swap_ptr (&x[1], 0, v3) == v1);
149 ASSERT (x[1] == v1);
150
151 ASSERT (atomic_compare_and_swap_ptr (&x[1], 4, v1) == v1);
152 ASSERT (x[1] == v1);
153
154 ASSERT (atomic_compare_and_swap_ptr (&x[1], v1, v2) == v1);
155 ASSERT (x[1] == v2);
156
157 ASSERT (x[0] == 0xDEADBEEFU);
158 ASSERT (x[2] == 0xDEADBEEFU);
159 }
160
161
162 {
163 void * (*funcs[2]) (void *) = { int_mutator_thread, ptr_mutator_thread };
164 int f;
165 for (f = 0; f < 2; f++)
166 {
167 void * (*func) (void *) = funcs[f];
168 int i, j;
169 gl_thread_t threads[THREAD_COUNT];
170
171
172 for (i = 0; i < THREAD_COUNT; i++)
173 for (j = 0; j < 5; j++)
174 counter[i][j] = 0;
175
176
177 for (i = 0; i < THREAD_COUNT; i++)
178 threads[i] = gl_thread_create (func, &counter[i][0]);
179
180
181 for (i = 0; i < THREAD_COUNT; i++)
182 gl_thread_join (threads[i], NULL);
183
184
185 unsigned int sum[5];
186 for (j = 0; j < 5; j++)
187 {
188 sum[j] = 0;
189 for (i = 0; i < THREAD_COUNT; i++)
190 sum[j] += counter[i][j];
191 }
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208 printf ("Counters: %u %u %u %u %u\n",
209 sum[0], sum[3], sum[1], sum[4], sum[2]);
210 ASSERT ((sum[0] == sum[3] || sum[0] == sum[3] + 1)
211 && (sum[3] == sum[1] || sum[3] == sum[1] + 1)
212 && (sum[1] == sum[4] || sum[1] == sum[4] + 1)
213 && (sum[4] == sum[2] || sum[4] == sum[2] + 1)
214 && (sum[2] + 1 == sum[0] || sum[2] == sum[0]));
215 }
216 }
217
218 return 0;
219 }
220
221 #else
222
223
224
225 #include <stdio.h>
226
227 int
228 main ()
229 {
230 fputs ("Skipping test: multithreading not enabled\n", stderr);
231 return 77;
232 }
233
234 #endif