Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2013, 2014 Nicira, Inc.
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at:
7 : : *
8 : : * http://www.apache.org/licenses/LICENSE-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : #include <config.h>
18 : : #undef NDEBUG
19 : : #include "fatal-signal.h"
20 : : #include "ovs-atomic.h"
21 : : #include "ovstest.h"
22 : : #include "ovs-thread.h"
23 : : #include "timeval.h"
24 : : #include "util.h"
25 : : #include "openvswitch/vlog.h"
26 : :
27 : 1174 : VLOG_DEFINE_THIS_MODULE(test_atomic);
28 : :
29 : : #define TEST_ATOMIC_TYPE(ATOMIC_TYPE, BASE_TYPE) \
30 : : { \
31 : : ATOMIC_TYPE x = ATOMIC_VAR_INIT(1); \
32 : : BASE_TYPE value, orig; \
33 : : \
34 : : atomic_read(&x, &value); \
35 : : ovs_assert(value == 1); \
36 : : \
37 : : atomic_store(&x, 2); \
38 : : atomic_read(&x, &value); \
39 : : ovs_assert(value == 2); \
40 : : \
41 : : atomic_init(&x, 3); \
42 : : atomic_read(&x, &value); \
43 : : ovs_assert(value == 3); \
44 : : \
45 : : atomic_add(&x, 1, &orig); \
46 : : ovs_assert(orig == 3); \
47 : : atomic_read(&x, &value); \
48 : : ovs_assert(value == 4); \
49 : : \
50 : : atomic_sub(&x, 2, &orig); \
51 : : ovs_assert(orig == 4); \
52 : : atomic_read(&x, &value); \
53 : : ovs_assert(value == 2); \
54 : : \
55 : : atomic_or(&x, 6, &orig); \
56 : : ovs_assert(orig == 2); \
57 : : atomic_read(&x, &value); \
58 : : ovs_assert(value == 6); \
59 : : \
60 : : atomic_and(&x, 10, &orig); \
61 : : ovs_assert(orig == 6); \
62 : : atomic_read(&x, &value); \
63 : : ovs_assert(value == 2); \
64 : : \
65 : : atomic_xor(&x, 10, &orig); \
66 : : ovs_assert(orig == 2); \
67 : : atomic_read(&x, &value); \
68 : : ovs_assert(value == 8); \
69 : : }
70 : :
71 : : #define TEST_ATOMIC_TYPE_EXPLICIT(ATOMIC_TYPE, BASE_TYPE, \
72 : : ORDER_READ, ORDER_STORE, ORDER_RMW) \
73 : : { \
74 : : ATOMIC_TYPE x = ATOMIC_VAR_INIT(1); \
75 : : BASE_TYPE value, orig; \
76 : : \
77 : : atomic_read_explicit(&x, &value, ORDER_READ); \
78 : : ovs_assert(value == 1); \
79 : : \
80 : : atomic_store_explicit(&x, 2, ORDER_STORE); \
81 : : atomic_read_explicit(&x, &value, ORDER_READ); \
82 : : ovs_assert(value == 2); \
83 : : \
84 : : atomic_init(&x, 3); \
85 : : atomic_read_explicit(&x, &value, ORDER_READ); \
86 : : ovs_assert(value == 3); \
87 : : \
88 : : atomic_add_explicit(&x, 1, &orig, ORDER_RMW); \
89 : : ovs_assert(orig == 3); \
90 : : atomic_read_explicit(&x, &value, ORDER_READ); \
91 : : ovs_assert(value == 4); \
92 : : \
93 : : atomic_sub_explicit(&x, 2, &orig, ORDER_RMW); \
94 : : ovs_assert(orig == 4); \
95 : : atomic_read_explicit(&x, &value, ORDER_READ); \
96 : : ovs_assert(value == 2); \
97 : : \
98 : : atomic_or_explicit(&x, 6, &orig, ORDER_RMW); \
99 : : ovs_assert(orig == 2); \
100 : : atomic_read_explicit(&x, &value, ORDER_READ); \
101 : : ovs_assert(value == 6); \
102 : : \
103 : : atomic_and_explicit(&x, 10, &orig, ORDER_RMW); \
104 : : ovs_assert(orig == 6); \
105 : : atomic_read_explicit(&x, &value, ORDER_READ); \
106 : : ovs_assert(value == 2); \
107 : : \
108 : : atomic_xor_explicit(&x, 10, &orig, ORDER_RMW); \
109 : : ovs_assert(orig == 2); \
110 : : atomic_read_explicit(&x, &value, ORDER_READ); \
111 : : ovs_assert(value == 8); \
112 : : }
113 : :
114 : :
115 : : #define TEST_ATOMIC_ORDER(ORDER_READ, ORDER_STORE, ORDER_RMW) \
116 : : { \
117 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_char, char, \
118 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
119 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_uchar, unsigned char, \
120 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
121 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_schar, signed char, \
122 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
123 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_short, short, \
124 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
125 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_ushort, unsigned short, \
126 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
127 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_int, int, \
128 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
129 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_uint, unsigned int, \
130 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
131 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_long, long int, \
132 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
133 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_ulong, unsigned long int, \
134 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
135 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_llong, long long int, \
136 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
137 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_ullong, unsigned long long int, \
138 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
139 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_size_t, size_t, \
140 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
141 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_ptrdiff_t, ptrdiff_t, \
142 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
143 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_intmax_t, intmax_t, \
144 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
145 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_uintmax_t, uintmax_t, \
146 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
147 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_intptr_t, intptr_t, \
148 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
149 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_uintptr_t, uintptr_t, \
150 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
151 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_uint8_t, uint8_t, \
152 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
153 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_int8_t, int8_t, \
154 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
155 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_uint16_t, uint16_t, \
156 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
157 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_int16_t, int16_t, \
158 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
159 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_uint32_t, uint32_t, \
160 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
161 : : TEST_ATOMIC_TYPE_EXPLICIT(atomic_int32_t, int32_t, \
162 : : ORDER_READ, ORDER_STORE, ORDER_RMW); \
163 : : }
164 : :
165 : : static void
166 : 1 : test_atomic_flag(void)
167 : : {
168 : 1 : atomic_flag flag = ATOMIC_FLAG_INIT;
169 [ - + ]: 1 : ovs_assert(atomic_flag_test_and_set(&flag) == false);
170 [ - + ]: 1 : ovs_assert(atomic_flag_test_and_set(&flag) == true);
171 : 1 : atomic_flag_clear(&flag);
172 [ - + ]: 1 : ovs_assert(atomic_flag_test_and_set(&flag) == false);
173 : 1 : }
174 : :
175 : : static uint32_t a;
176 : :
177 : : struct atomic_aux {
178 : : ATOMIC(uint64_t) count;
179 : : uint32_t b;
180 : : ATOMIC(uint32_t *) data;
181 : : ATOMIC(uint64_t) data64;
182 : : };
183 : :
184 : : static ATOMIC(struct atomic_aux *) paux = ATOMIC_VAR_INIT(NULL);
185 : : static struct atomic_aux *auxes = NULL;
186 : :
187 : : #define ATOMIC_ITEM_COUNT 1000000
188 : : #define DURATION 5000
189 : :
190 : : static void *
191 : 1 : atomic_consumer(void * arg1 OVS_UNUSED)
192 : : {
193 : 1 : struct atomic_aux *old_aux = NULL;
194 : : uint64_t count;
195 : 1 : long long int stop_time = time_msec() + DURATION;
196 : :
197 : : do {
198 : : struct atomic_aux *aux;
199 : : uint32_t b;
200 : :
201 : : /* Wait for a new item. We may not be fast enough to process every
202 : : * item, but we are guaranteed to see the last one. */
203 : : do {
204 : 7624940 : atomic_read_explicit(&paux, &aux, memory_order_consume);
205 [ + + ]: 7624940 : } while (aux == old_aux);
206 : :
207 : 5 : b = aux->b;
208 : 5 : atomic_read_explicit(&aux->count, &count, memory_order_relaxed);
209 [ - + ]: 5 : ovs_assert(b == count + 42);
210 : :
211 : 5 : old_aux = aux;
212 [ + + ][ + - ]: 5 : } while (count < ATOMIC_ITEM_COUNT - 1 && time_msec() < stop_time);
213 : :
214 [ - + ]: 1 : if (time_msec() >= stop_time) {
215 [ # # ]: 0 : if (count < 10) {
216 [ # # ]: 0 : VLOG_WARN("atomic_consumer test stopped due to excessive runtime. "
217 : : "Count = %"PRIu64, count);
218 : : }
219 : : }
220 : :
221 : 1 : return NULL;
222 : : }
223 : :
224 : : static void *
225 : 1 : atomic_producer(void * arg1 OVS_UNUSED)
226 : : {
227 : : size_t i;
228 : :
229 [ + + ]: 1000001 : for (i = 0; i < ATOMIC_ITEM_COUNT; i++) {
230 : 1000000 : struct atomic_aux *aux = &auxes[i];
231 : :
232 : 1000000 : aux->count = ATOMIC_VAR_INIT(i);
233 : 1000000 : aux->b = i + 42;
234 : :
235 : : /* Publish the new item. */
236 : 1000000 : atomic_store_explicit(&paux, aux, memory_order_release);
237 : : }
238 : :
239 : 1 : return NULL;
240 : : }
241 : :
242 : : static void
243 : 1 : test_cons_rel(void)
244 : : {
245 : : pthread_t reader, writer;
246 : :
247 : 1 : atomic_init(&paux, NULL);
248 : :
249 : 1 : auxes = xmalloc(sizeof *auxes * ATOMIC_ITEM_COUNT);
250 : :
251 : 1 : reader = ovs_thread_create("consumer", atomic_consumer, NULL);
252 : 1 : writer = ovs_thread_create("producer", atomic_producer, NULL);
253 : :
254 : 1 : xpthread_join(reader, NULL);
255 : 1 : xpthread_join(writer, NULL);
256 : :
257 : 1 : free(auxes);
258 : 1 : }
259 : :
260 : : static void *
261 : 1 : atomic_reader(void *aux_)
262 : : {
263 : 1 : struct atomic_aux *aux = aux_;
264 : : uint64_t count;
265 : : uint64_t data;
266 : 1 : long long int now = time_msec();
267 : 1 : long long int stop_time = now + DURATION;
268 : :
269 : : do {
270 : : /* Non-synchronized add. */
271 : 776487 : atomic_add_explicit(&aux->count, 1, &count, memory_order_relaxed);
272 : :
273 : : do {
274 : 5444714 : atomic_read_explicit(&aux->data64, &data, memory_order_acquire);
275 [ + + ][ + + ]: 5444714 : } while (!data && (now = time_msec()) < stop_time);
276 : :
277 [ + + ]: 776487 : if (now >= stop_time) {
278 [ - + ]: 1 : if (count < 10) {
279 [ # # ]: 0 : VLOG_WARN("atomic_reader test stopped due to excessive "
280 : : "runtime. Count = %"PRIu64, count);
281 : : }
282 : 1 : break;
283 : : }
284 : :
285 [ + - ][ + - ]: 776486 : ovs_assert(data == a && data == aux->b && a == aux->b);
[ + - ][ - + ]
286 : :
287 : 776486 : atomic_read_explicit(&aux->count, &count, memory_order_relaxed);
288 : :
289 [ + - ][ + - ]: 776486 : ovs_assert(count == 2 * a && count == 2 * aux->b && count == 2 * data);
[ + - ][ - + ]
290 : :
291 : 776486 : atomic_store_explicit(&aux->data64, UINT64_C(0), memory_order_release);
292 [ + - ]: 776486 : } while (count < 2 * ATOMIC_ITEM_COUNT);
293 : :
294 : 1 : return NULL;
295 : : }
296 : :
297 : : static void *
298 : 1 : atomic_writer(void *aux_)
299 : : {
300 : 1 : struct atomic_aux *aux = aux_;
301 : : uint64_t old_count;
302 : : uint64_t data;
303 : : size_t i;
304 : 1 : long long int now = time_msec();
305 : 1 : long long int stop_time = now + DURATION;
306 : :
307 [ + - ]: 776488 : for (i = 0; i < ATOMIC_ITEM_COUNT; i++) {
308 : : /* Wait for the reader to be done with the data. */
309 : : do {
310 : 4865441 : atomic_read_explicit(&aux->data64, &data, memory_order_acquire);
311 [ + + ][ + + ]: 4865441 : } while (data && (now = time_msec()) < stop_time);
312 : :
313 [ + + ]: 776488 : if (now >= stop_time) {
314 [ - + ]: 1 : if (i < 10) {
315 [ # # ]: 0 : VLOG_WARN("atomic_writer test stopped due to excessive "
316 : : "runtime, Count = %"PRIuSIZE, i);
317 : : }
318 : 1 : break;
319 : : }
320 : :
321 : 776487 : a = i + 1;
322 : 776487 : atomic_add_explicit(&aux->count, 1, &old_count, memory_order_relaxed);
323 : 776487 : aux->b++;
324 [ + + ]: 776487 : atomic_store_explicit(&aux->data64,
325 : : (i & 1) ? (uint64_t)aux->b : a, memory_order_release);
326 : : }
327 : :
328 : 1 : return NULL;
329 : : }
330 : :
331 : : static void
332 : 1 : test_acq_rel(void)
333 : : {
334 : : pthread_t reader, writer;
335 : 1 : struct atomic_aux *aux = xmalloc(sizeof *aux);
336 : :
337 : 1 : a = 0;
338 : 1 : aux->b = 0;
339 : :
340 : 1 : aux->count = ATOMIC_VAR_INIT(0);
341 : 1 : atomic_init(&aux->data, NULL);
342 : 1 : aux->data64 = ATOMIC_VAR_INIT(0);
343 : :
344 : 1 : reader = ovs_thread_create("reader", atomic_reader, aux);
345 : 1 : writer = ovs_thread_create("writer", atomic_writer, aux);
346 : :
347 : 1 : xpthread_join(reader, NULL);
348 : 1 : xpthread_join(writer, NULL);
349 : 1 : free(aux);
350 : 1 : }
351 : :
352 : : static void
353 : 1 : test_atomic_plain(void)
354 : : {
355 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_char, char);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
356 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_uchar, unsigned char);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
357 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_schar, signed char);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
358 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_short, short);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
359 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_ushort, unsigned short);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
360 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_int, int);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
361 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_uint, unsigned int);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
362 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_long, long int);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
363 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_ulong, unsigned long int);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
364 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_llong, long long int);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
365 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_ullong, unsigned long long int);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
366 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_size_t, size_t);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
367 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_ptrdiff_t, ptrdiff_t);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
368 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_intmax_t, intmax_t);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
369 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_uintmax_t, uintmax_t);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
370 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_intptr_t, intptr_t);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
371 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_uintptr_t, uintptr_t);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
372 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_uint8_t, uint8_t);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
373 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_int8_t, int8_t);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
374 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_uint16_t, uint16_t);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
375 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_int16_t, int16_t);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
376 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_uint32_t, uint32_t);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
377 [ - + ][ - + ]: 1 : TEST_ATOMIC_TYPE(atomic_int32_t, int32_t);
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
378 : 1 : }
379 : :
380 : : static void
381 : 1 : test_atomic_relaxed(void)
382 : : {
383 [ - + ][ - + ]: 1 : TEST_ATOMIC_ORDER(memory_order_relaxed, memory_order_relaxed,
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
384 : : memory_order_relaxed);
385 : 1 : }
386 : :
387 : : static void
388 : 1 : test_atomic_consume(void)
389 : : {
390 [ - + ][ - + ]: 1 : TEST_ATOMIC_ORDER(memory_order_consume, memory_order_release,
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
391 : : memory_order_release);
392 : 1 : }
393 : :
394 : : static void
395 : 1 : test_atomic_acquire(void)
396 : : {
397 [ - + ][ - + ]: 1 : TEST_ATOMIC_ORDER(memory_order_acquire, memory_order_release,
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
398 : : memory_order_release);
399 : 1 : }
400 : :
401 : : static void
402 : 1 : test_atomic_acq_rel(void)
403 : : {
404 [ - + ][ - + ]: 1 : TEST_ATOMIC_ORDER(memory_order_acquire, memory_order_release,
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
405 : : memory_order_acq_rel);
406 : 1 : }
407 : :
408 : : static void
409 : 1 : test_atomic_seq_cst(void)
410 : : {
411 [ - + ][ - + ]: 1 : TEST_ATOMIC_ORDER(memory_order_seq_cst, memory_order_seq_cst,
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ]
412 : : memory_order_seq_cst);
413 : 1 : }
414 : :
415 : : static void
416 : 1 : test_atomic_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
417 : : {
418 : 1 : fatal_signal_init();
419 : 1 : test_atomic_plain();
420 : 1 : test_atomic_relaxed();
421 : 1 : test_atomic_consume();
422 : 1 : test_atomic_acquire();
423 : 1 : test_atomic_acq_rel();
424 : 1 : test_atomic_seq_cst();
425 : :
426 : 1 : test_atomic_flag();
427 : :
428 : 1 : test_acq_rel();
429 : 1 : test_cons_rel();
430 : 1 : }
431 : :
432 : 1176 : OVSTEST_REGISTER("test-atomic", test_atomic_main);
|