Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
atomic_ops.h
1/*
2 * THIS FILE IS AUTO-GENERATED USING `atomic_ops_gen.py'.
3 */
4
5#ifndef ROC_CORE_ATOMIC_OPS_H_
6#define ROC_CORE_ATOMIC_OPS_H_
7
8#include "roc_core/stddefs.h"
9
10#include <atomic_ops.h>
11
12namespace roc {
13namespace core {
14
15//! Atomic operations.
16class AtomicOps {
17public:
18 #ifdef AO_HAVE_nop_read
19 //! Acquire memory barrier.
20 static inline void fence_acquire() {
21 AO_nop_read();
22 }
23 #endif // AO_HAVE_nop_read
24
25 #ifdef AO_HAVE_nop_write
26 //! Release memory barrier.
27 static inline void fence_release() {
28 AO_nop_write();
29 }
30 #endif // AO_HAVE_nop_write
31
32 #ifdef AO_HAVE_nop_full
33 //! Full memory barrier.
34 static inline void fence_seq_cst() {
35 AO_nop_full();
36 }
37 #endif // AO_HAVE_nop_full
38
39 // overloads for unsigned char
40
41 #ifdef AO_HAVE_char_load
42 //! Atomic load (no barrier).
43 static inline unsigned char load_relaxed(unsigned char const& var) {
44 struct TypeCheck {
45 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
46 };
47 return (unsigned char)AO_char_load((unsigned char const*)&var);
48 }
49 #endif // AO_HAVE_char_load
50
51 #ifdef AO_HAVE_char_store
52 //! Atomic store (no barrier).
53 static inline void store_relaxed(unsigned char& var, unsigned char val) {
54 struct TypeCheck {
55 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
56 };
57 AO_char_store((unsigned char*)&var, (unsigned char)val);
58 }
59 #endif // AO_HAVE_char_store
60
61 #ifdef AO_HAVE_char_fetch_compare_and_swap
62 //! Atomic exchange (no barrier).
63 static inline unsigned char exchange_relaxed(unsigned char& var, unsigned char val) {
64 struct TypeCheck {
65 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
66 };
67 unsigned char curr = AO_char_load((unsigned char*)&var);
68 unsigned char prev;
69 do {
70 prev = curr;
71 curr = AO_char_fetch_compare_and_swap((unsigned char*)&var, prev,
72 (unsigned char)val);
73 } while (curr != prev);
74 return (unsigned char)curr;
75 }
76 #endif // AO_HAVE_char_fetch_compare_and_swap
77
78 #ifdef AO_HAVE_char_fetch_compare_and_swap
79 //! Atomic compare-and-swap (no barrier).
80 static inline bool compare_exchange_relaxed(
81 unsigned char& var, unsigned char& exp, unsigned char des) {
82 struct TypeCheck {
83 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
84 };
85 unsigned char old = AO_char_fetch_compare_and_swap(
86 (unsigned char*)&var, (unsigned char)exp, (unsigned char)des);
87 const bool ret = ((unsigned char)exp == old);
88 exp = (unsigned char)old;
89 return ret;
90 }
91 #endif // AO_HAVE_char_fetch_compare_and_swap
92
93 #ifdef AO_HAVE_char_fetch_and_add
94 //! Atomic fetch-add (no barrier).
95 static inline unsigned char fetch_add_relaxed(unsigned char& var, unsigned char val) {
96 struct TypeCheck {
97 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
98 };
99 return (unsigned char)(
100 AO_char_fetch_and_add((unsigned char*)&var, (unsigned char)val));
101 }
102 #endif // AO_HAVE_char_fetch_and_add
103
104 #ifdef AO_HAVE_char_fetch_and_add
105 //! Atomic fetch-sub (no barrier).
106 static inline unsigned char fetch_sub_relaxed(unsigned char& var, unsigned char val) {
107 struct TypeCheck {
108 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
109 };
110 return (unsigned char)(
111 AO_char_fetch_and_add((unsigned char*)&var, (unsigned char)-val));
112 }
113 #endif // AO_HAVE_char_fetch_and_add
114
115 #ifdef AO_HAVE_char_fetch_compare_and_swap
116 //! Atomic fetch-and (no barrier).
117 static inline unsigned char fetch_and_relaxed(unsigned char& var, unsigned char val) {
118 struct TypeCheck {
119 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
120 };
121 unsigned char curr = AO_char_load((unsigned char*)&var);
122 unsigned char prev;
123 do {
124 prev = curr;
125 curr = AO_char_fetch_compare_and_swap((unsigned char*)&var, prev,
126 prev & (unsigned char)val);
127 } while (curr != prev);
128 return (unsigned char)curr;
129 }
130 #endif // AO_HAVE_char_fetch_compare_and_swap
131
132 #ifdef AO_HAVE_char_fetch_compare_and_swap
133 //! Atomic fetch-or (no barrier).
134 static inline unsigned char fetch_or_relaxed(unsigned char& var, unsigned char val) {
135 struct TypeCheck {
136 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
137 };
138 unsigned char curr = AO_char_load((unsigned char*)&var);
139 unsigned char prev;
140 do {
141 prev = curr;
142 curr = AO_char_fetch_compare_and_swap((unsigned char*)&var, prev,
143 prev | (unsigned char)val);
144 } while (curr != prev);
145 return (unsigned char)curr;
146 }
147 #endif // AO_HAVE_char_fetch_compare_and_swap
148
149 #ifdef AO_HAVE_char_fetch_compare_and_swap
150 //! Atomic fetch-xor (no barrier).
151 static inline unsigned char fetch_xor_relaxed(unsigned char& var, unsigned char val) {
152 struct TypeCheck {
153 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
154 };
155 unsigned char curr = AO_char_load((unsigned char*)&var);
156 unsigned char prev;
157 do {
158 prev = curr;
159 curr = AO_char_fetch_compare_and_swap((unsigned char*)&var, prev,
160 prev ^ (unsigned char)val);
161 } while (curr != prev);
162 return (unsigned char)curr;
163 }
164 #endif // AO_HAVE_char_fetch_compare_and_swap
165
166 #ifdef AO_HAVE_char_load_acquire
167 //! Atomic load (acquire barrier).
168 static inline unsigned char load_acquire(unsigned char const& var) {
169 struct TypeCheck {
170 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
171 };
172 return (unsigned char)AO_char_load_acquire((unsigned char const*)&var);
173 }
174 #endif // AO_HAVE_char_load_acquire
175
176 #ifdef AO_HAVE_char_fetch_compare_and_swap_acquire
177 //! Atomic exchange (acquire barrier).
178 static inline unsigned char exchange_acquire(unsigned char& var, unsigned char val) {
179 struct TypeCheck {
180 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
181 };
182 unsigned char curr = AO_char_load((unsigned char*)&var);
183 unsigned char prev;
184 do {
185 prev = curr;
186 curr = AO_char_fetch_compare_and_swap_acquire((unsigned char*)&var, prev,
187 (unsigned char)val);
188 } while (curr != prev);
189 return (unsigned char)curr;
190 }
191 #endif // AO_HAVE_char_fetch_compare_and_swap_acquire
192
193 #ifdef AO_HAVE_char_fetch_compare_and_swap_acquire
194 //! Atomic compare-and-swap (acquire barrier).
195 static inline bool compare_exchange_acquire(
196 unsigned char& var, unsigned char& exp, unsigned char des) {
197 struct TypeCheck {
198 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
199 };
200 unsigned char old = AO_char_fetch_compare_and_swap_acquire(
201 (unsigned char*)&var, (unsigned char)exp, (unsigned char)des);
202 const bool ret = ((unsigned char)exp == old);
203 exp = (unsigned char)old;
204 return ret;
205 }
206 #endif // AO_HAVE_char_fetch_compare_and_swap_acquire
207
208 #ifdef AO_HAVE_char_fetch_and_add_acquire
209 //! Atomic fetch-add (acquire barrier).
210 static inline unsigned char fetch_add_acquire(unsigned char& var, unsigned char val) {
211 struct TypeCheck {
212 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
213 };
214 return (unsigned char)(
215 AO_char_fetch_and_add_acquire((unsigned char*)&var, (unsigned char)val));
216 }
217 #endif // AO_HAVE_char_fetch_and_add_acquire
218
219 #ifdef AO_HAVE_char_fetch_and_add_acquire
220 //! Atomic fetch-sub (acquire barrier).
221 static inline unsigned char fetch_sub_acquire(unsigned char& var, unsigned char val) {
222 struct TypeCheck {
223 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
224 };
225 return (unsigned char)(
226 AO_char_fetch_and_add_acquire((unsigned char*)&var, (unsigned char)-val));
227 }
228 #endif // AO_HAVE_char_fetch_and_add_acquire
229
230 #ifdef AO_HAVE_char_fetch_compare_and_swap_acquire
231 //! Atomic fetch-and (acquire barrier).
232 static inline unsigned char fetch_and_acquire(unsigned char& var, unsigned char val) {
233 struct TypeCheck {
234 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
235 };
236 unsigned char curr = AO_char_load((unsigned char*)&var);
237 unsigned char prev;
238 do {
239 prev = curr;
240 curr = AO_char_fetch_compare_and_swap_acquire((unsigned char*)&var, prev,
241 prev & (unsigned char)val);
242 } while (curr != prev);
243 return (unsigned char)curr;
244 }
245 #endif // AO_HAVE_char_fetch_compare_and_swap_acquire
246
247 #ifdef AO_HAVE_char_fetch_compare_and_swap_acquire
248 //! Atomic fetch-or (acquire barrier).
249 static inline unsigned char fetch_or_acquire(unsigned char& var, unsigned char val) {
250 struct TypeCheck {
251 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
252 };
253 unsigned char curr = AO_char_load((unsigned char*)&var);
254 unsigned char prev;
255 do {
256 prev = curr;
257 curr = AO_char_fetch_compare_and_swap_acquire((unsigned char*)&var, prev,
258 prev | (unsigned char)val);
259 } while (curr != prev);
260 return (unsigned char)curr;
261 }
262 #endif // AO_HAVE_char_fetch_compare_and_swap_acquire
263
264 #ifdef AO_HAVE_char_fetch_compare_and_swap_acquire
265 //! Atomic fetch-xor (acquire barrier).
266 static inline unsigned char fetch_xor_acquire(unsigned char& var, unsigned char val) {
267 struct TypeCheck {
268 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
269 };
270 unsigned char curr = AO_char_load((unsigned char*)&var);
271 unsigned char prev;
272 do {
273 prev = curr;
274 curr = AO_char_fetch_compare_and_swap_acquire((unsigned char*)&var, prev,
275 prev ^ (unsigned char)val);
276 } while (curr != prev);
277 return (unsigned char)curr;
278 }
279 #endif // AO_HAVE_char_fetch_compare_and_swap_acquire
280
281 #ifdef AO_HAVE_char_store_release
282 //! Atomic store (release barrier).
283 static inline void store_release(unsigned char& var, unsigned char val) {
284 struct TypeCheck {
285 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
286 };
287 AO_char_store_release((unsigned char*)&var, (unsigned char)val);
288 }
289 #endif // AO_HAVE_char_store_release
290
291 #ifdef AO_HAVE_char_fetch_compare_and_swap_release
292 //! Atomic exchange (release barrier).
293 static inline unsigned char exchange_release(unsigned char& var, unsigned char val) {
294 struct TypeCheck {
295 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
296 };
297 unsigned char curr = AO_char_load((unsigned char*)&var);
298 unsigned char prev;
299 do {
300 prev = curr;
301 curr = AO_char_fetch_compare_and_swap_release((unsigned char*)&var, prev,
302 (unsigned char)val);
303 } while (curr != prev);
304 return (unsigned char)curr;
305 }
306 #endif // AO_HAVE_char_fetch_compare_and_swap_release
307
308 #ifdef AO_HAVE_char_fetch_compare_and_swap_release
309 //! Atomic compare-and-swap (release barrier).
310 static inline bool compare_exchange_release(
311 unsigned char& var, unsigned char& exp, unsigned char des) {
312 struct TypeCheck {
313 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
314 };
315 unsigned char old = AO_char_fetch_compare_and_swap_release(
316 (unsigned char*)&var, (unsigned char)exp, (unsigned char)des);
317 const bool ret = ((unsigned char)exp == old);
318 exp = (unsigned char)old;
319 return ret;
320 }
321 #endif // AO_HAVE_char_fetch_compare_and_swap_release
322
323 #ifdef AO_HAVE_char_fetch_and_add_release
324 //! Atomic fetch-add (release barrier).
325 static inline unsigned char fetch_add_release(unsigned char& var, unsigned char val) {
326 struct TypeCheck {
327 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
328 };
329 return (unsigned char)(
330 AO_char_fetch_and_add_release((unsigned char*)&var, (unsigned char)val));
331 }
332 #endif // AO_HAVE_char_fetch_and_add_release
333
334 #ifdef AO_HAVE_char_fetch_and_add_release
335 //! Atomic fetch-sub (release barrier).
336 static inline unsigned char fetch_sub_release(unsigned char& var, unsigned char val) {
337 struct TypeCheck {
338 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
339 };
340 return (unsigned char)(
341 AO_char_fetch_and_add_release((unsigned char*)&var, (unsigned char)-val));
342 }
343 #endif // AO_HAVE_char_fetch_and_add_release
344
345 #ifdef AO_HAVE_char_fetch_compare_and_swap_release
346 //! Atomic fetch-and (release barrier).
347 static inline unsigned char fetch_and_release(unsigned char& var, unsigned char val) {
348 struct TypeCheck {
349 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
350 };
351 unsigned char curr = AO_char_load((unsigned char*)&var);
352 unsigned char prev;
353 do {
354 prev = curr;
355 curr = AO_char_fetch_compare_and_swap_release((unsigned char*)&var, prev,
356 prev & (unsigned char)val);
357 } while (curr != prev);
358 return (unsigned char)curr;
359 }
360 #endif // AO_HAVE_char_fetch_compare_and_swap_release
361
362 #ifdef AO_HAVE_char_fetch_compare_and_swap_release
363 //! Atomic fetch-or (release barrier).
364 static inline unsigned char fetch_or_release(unsigned char& var, unsigned char val) {
365 struct TypeCheck {
366 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
367 };
368 unsigned char curr = AO_char_load((unsigned char*)&var);
369 unsigned char prev;
370 do {
371 prev = curr;
372 curr = AO_char_fetch_compare_and_swap_release((unsigned char*)&var, prev,
373 prev | (unsigned char)val);
374 } while (curr != prev);
375 return (unsigned char)curr;
376 }
377 #endif // AO_HAVE_char_fetch_compare_and_swap_release
378
379 #ifdef AO_HAVE_char_fetch_compare_and_swap_release
380 //! Atomic fetch-xor (release barrier).
381 static inline unsigned char fetch_xor_release(unsigned char& var, unsigned char val) {
382 struct TypeCheck {
383 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
384 };
385 unsigned char curr = AO_char_load((unsigned char*)&var);
386 unsigned char prev;
387 do {
388 prev = curr;
389 curr = AO_char_fetch_compare_and_swap_release((unsigned char*)&var, prev,
390 prev ^ (unsigned char)val);
391 } while (curr != prev);
392 return (unsigned char)curr;
393 }
394 #endif // AO_HAVE_char_fetch_compare_and_swap_release
395
396 #ifdef AO_HAVE_char_fetch_compare_and_swap_full
397 //! Atomic exchange (acquire-release barrier).
398 static inline unsigned char exchange_acq_rel(unsigned char& var, unsigned char val) {
399 struct TypeCheck {
400 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
401 };
402 unsigned char curr = AO_char_load((unsigned char*)&var);
403 unsigned char prev;
404 do {
405 prev = curr;
406 curr = AO_char_fetch_compare_and_swap_full((unsigned char*)&var, prev,
407 (unsigned char)val);
408 } while (curr != prev);
409 return (unsigned char)curr;
410 }
411 #endif // AO_HAVE_char_fetch_compare_and_swap_full
412
413 #ifdef AO_HAVE_char_fetch_compare_and_swap_full
414 //! Atomic compare-and-swap (acquire-release barrier).
415 static inline bool compare_exchange_acq_rel(
416 unsigned char& var, unsigned char& exp, unsigned char des) {
417 struct TypeCheck {
418 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
419 };
420 unsigned char old = AO_char_fetch_compare_and_swap_full(
421 (unsigned char*)&var, (unsigned char)exp, (unsigned char)des);
422 const bool ret = ((unsigned char)exp == old);
423 exp = (unsigned char)old;
424 return ret;
425 }
426 #endif // AO_HAVE_char_fetch_compare_and_swap_full
427
428 #ifdef AO_HAVE_char_load_full
429 //! Atomic load (full barrier).
430 static inline unsigned char load_seq_cst(unsigned char const& var) {
431 struct TypeCheck {
432 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
433 };
434 return (unsigned char)AO_char_load_full((unsigned char const*)&var);
435 }
436 #endif // AO_HAVE_char_load_full
437
438 #ifdef AO_HAVE_char_store_full
439 //! Atomic store (full barrier).
440 static inline void store_seq_cst(unsigned char& var, unsigned char val) {
441 struct TypeCheck {
442 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
443 };
444 AO_char_store_full((unsigned char*)&var, (unsigned char)val);
445 }
446 #endif // AO_HAVE_char_store_full
447
448 #ifdef AO_HAVE_char_fetch_compare_and_swap
449 //! Atomic exchange (full barrier).
450 static inline unsigned char exchange_seq_cst(unsigned char& var, unsigned char val) {
451 struct TypeCheck {
452 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
453 };
454 AO_nop_full();
455 unsigned char curr = AO_char_load((unsigned char*)&var);
456 unsigned char prev;
457 do {
458 prev = curr;
459 curr = AO_char_fetch_compare_and_swap((unsigned char*)&var, prev,
460 (unsigned char)val);
461 AO_nop_full();
462 } while (curr != prev);
463 return (unsigned char)curr;
464 }
465 #endif // AO_HAVE_char_fetch_compare_and_swap
466
467 #ifdef AO_HAVE_char_fetch_compare_and_swap
468 //! Atomic compare-and-swap (full barrier).
469 static inline bool compare_exchange_seq_cst(
470 unsigned char& var, unsigned char& exp, unsigned char des) {
471 struct TypeCheck {
472 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
473 };
474 AO_nop_full();
475 unsigned char old = AO_char_fetch_compare_and_swap(
476 (unsigned char*)&var, (unsigned char)exp, (unsigned char)des);
477 const bool ret = ((unsigned char)exp == old);
478 if (ret) {
479 AO_nop_full();
480 }
481 exp = (unsigned char)old;
482 return ret;
483 }
484 #endif // AO_HAVE_char_fetch_compare_and_swap
485
486 #ifdef AO_HAVE_char_fetch_and_add_full
487 //! Atomic fetch-add (full barrier).
488 static inline unsigned char fetch_add_seq_cst(unsigned char& var, unsigned char val) {
489 struct TypeCheck {
490 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
491 };
492 return (unsigned char)(
493 AO_char_fetch_and_add_full((unsigned char*)&var, (unsigned char)val));
494 }
495 #endif // AO_HAVE_char_fetch_and_add_full
496
497 #ifdef AO_HAVE_char_fetch_and_add_full
498 //! Atomic fetch-sub (full barrier).
499 static inline unsigned char fetch_sub_seq_cst(unsigned char& var, unsigned char val) {
500 struct TypeCheck {
501 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
502 };
503 return (unsigned char)(
504 AO_char_fetch_and_add_full((unsigned char*)&var, (unsigned char)-val));
505 }
506 #endif // AO_HAVE_char_fetch_and_add_full
507
508 #ifdef AO_HAVE_char_fetch_compare_and_swap_full
509 //! Atomic fetch-and (full barrier).
510 static inline unsigned char fetch_and_seq_cst(unsigned char& var, unsigned char val) {
511 struct TypeCheck {
512 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
513 };
514 AO_nop_full();
515 unsigned char curr = AO_char_load((unsigned char*)&var);
516 unsigned char prev;
517 do {
518 prev = curr;
519 curr = AO_char_fetch_compare_and_swap((unsigned char*)&var, prev,
520 prev & (unsigned char)val);
521 AO_nop_full();
522 } while (curr != prev);
523 return (unsigned char)curr;
524 }
525 #endif // AO_HAVE_char_fetch_compare_and_swap_full
526
527 #ifdef AO_HAVE_char_fetch_compare_and_swap_full
528 //! Atomic fetch-or (full barrier).
529 static inline unsigned char fetch_or_seq_cst(unsigned char& var, unsigned char val) {
530 struct TypeCheck {
531 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
532 };
533 AO_nop_full();
534 unsigned char curr = AO_char_load((unsigned char*)&var);
535 unsigned char prev;
536 do {
537 prev = curr;
538 curr = AO_char_fetch_compare_and_swap((unsigned char*)&var, prev,
539 prev | (unsigned char)val);
540 AO_nop_full();
541 } while (curr != prev);
542 return (unsigned char)curr;
543 }
544 #endif // AO_HAVE_char_fetch_compare_and_swap_full
545
546 #ifdef AO_HAVE_char_fetch_compare_and_swap_full
547 //! Atomic fetch-xor (full barrier).
548 static inline unsigned char fetch_xor_seq_cst(unsigned char& var, unsigned char val) {
549 struct TypeCheck {
550 int f : sizeof(unsigned char) == sizeof(unsigned char) ? 1 : -1;
551 };
552 AO_nop_full();
553 unsigned char curr = AO_char_load((unsigned char*)&var);
554 unsigned char prev;
555 do {
556 prev = curr;
557 curr = AO_char_fetch_compare_and_swap((unsigned char*)&var, prev,
558 prev ^ (unsigned char)val);
559 AO_nop_full();
560 } while (curr != prev);
561 return (unsigned char)curr;
562 }
563 #endif // AO_HAVE_char_fetch_compare_and_swap_full
564
565 // overloads for char
566
567 #ifdef AO_HAVE_char_load
568 //! Atomic load (no barrier).
569 static inline char load_relaxed(char const& var) {
570 struct TypeCheck {
571 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
572 };
573 return (char)AO_char_load((unsigned char const*)&var);
574 }
575 #endif // AO_HAVE_char_load
576
577 #ifdef AO_HAVE_char_store
578 //! Atomic store (no barrier).
579 static inline void store_relaxed(char& var, char val) {
580 struct TypeCheck {
581 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
582 };
583 AO_char_store((unsigned char*)&var, (unsigned char)val);
584 }
585 #endif // AO_HAVE_char_store
586
587 #ifdef AO_HAVE_char_fetch_compare_and_swap
588 //! Atomic exchange (no barrier).
589 static inline char exchange_relaxed(char& var, char val) {
590 struct TypeCheck {
591 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
592 };
593 unsigned char curr = AO_char_load((unsigned char*)&var);
594 unsigned char prev;
595 do {
596 prev = curr;
597 curr = AO_char_fetch_compare_and_swap((unsigned char*)&var, prev,
598 (unsigned char)val);
599 } while (curr != prev);
600 return (char)curr;
601 }
602 #endif // AO_HAVE_char_fetch_compare_and_swap
603
604 #ifdef AO_HAVE_char_fetch_compare_and_swap
605 //! Atomic compare-and-swap (no barrier).
606 static inline bool compare_exchange_relaxed(
607 char& var, char& exp, char des) {
608 struct TypeCheck {
609 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
610 };
611 unsigned char old = AO_char_fetch_compare_and_swap(
612 (unsigned char*)&var, (unsigned char)exp, (unsigned char)des);
613 const bool ret = ((unsigned char)exp == old);
614 exp = (char)old;
615 return ret;
616 }
617 #endif // AO_HAVE_char_fetch_compare_and_swap
618
619 #ifdef AO_HAVE_char_fetch_and_add
620 //! Atomic fetch-add (no barrier).
621 static inline char fetch_add_relaxed(char& var, char val) {
622 struct TypeCheck {
623 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
624 };
625 return (char)(
626 AO_char_fetch_and_add((unsigned char*)&var, (unsigned char)val));
627 }
628 #endif // AO_HAVE_char_fetch_and_add
629
630 #ifdef AO_HAVE_char_fetch_and_add
631 //! Atomic fetch-sub (no barrier).
632 static inline char fetch_sub_relaxed(char& var, char val) {
633 struct TypeCheck {
634 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
635 };
636 return (char)(
637 AO_char_fetch_and_add((unsigned char*)&var, (unsigned char)-val));
638 }
639 #endif // AO_HAVE_char_fetch_and_add
640
641 #ifdef AO_HAVE_char_fetch_compare_and_swap
642 //! Atomic fetch-and (no barrier).
643 static inline char fetch_and_relaxed(char& var, char val) {
644 struct TypeCheck {
645 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
646 };
647 unsigned char curr = AO_char_load((unsigned char*)&var);
648 unsigned char prev;
649 do {
650 prev = curr;
651 curr = AO_char_fetch_compare_and_swap((unsigned char*)&var, prev,
652 prev & (unsigned char)val);
653 } while (curr != prev);
654 return (char)curr;
655 }
656 #endif // AO_HAVE_char_fetch_compare_and_swap
657
658 #ifdef AO_HAVE_char_fetch_compare_and_swap
659 //! Atomic fetch-or (no barrier).
660 static inline char fetch_or_relaxed(char& var, char val) {
661 struct TypeCheck {
662 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
663 };
664 unsigned char curr = AO_char_load((unsigned char*)&var);
665 unsigned char prev;
666 do {
667 prev = curr;
668 curr = AO_char_fetch_compare_and_swap((unsigned char*)&var, prev,
669 prev | (unsigned char)val);
670 } while (curr != prev);
671 return (char)curr;
672 }
673 #endif // AO_HAVE_char_fetch_compare_and_swap
674
675 #ifdef AO_HAVE_char_fetch_compare_and_swap
676 //! Atomic fetch-xor (no barrier).
677 static inline char fetch_xor_relaxed(char& var, char val) {
678 struct TypeCheck {
679 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
680 };
681 unsigned char curr = AO_char_load((unsigned char*)&var);
682 unsigned char prev;
683 do {
684 prev = curr;
685 curr = AO_char_fetch_compare_and_swap((unsigned char*)&var, prev,
686 prev ^ (unsigned char)val);
687 } while (curr != prev);
688 return (char)curr;
689 }
690 #endif // AO_HAVE_char_fetch_compare_and_swap
691
692 #ifdef AO_HAVE_char_load_acquire
693 //! Atomic load (acquire barrier).
694 static inline char load_acquire(char const& var) {
695 struct TypeCheck {
696 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
697 };
698 return (char)AO_char_load_acquire((unsigned char const*)&var);
699 }
700 #endif // AO_HAVE_char_load_acquire
701
702 #ifdef AO_HAVE_char_fetch_compare_and_swap_acquire
703 //! Atomic exchange (acquire barrier).
704 static inline char exchange_acquire(char& var, char val) {
705 struct TypeCheck {
706 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
707 };
708 unsigned char curr = AO_char_load((unsigned char*)&var);
709 unsigned char prev;
710 do {
711 prev = curr;
712 curr = AO_char_fetch_compare_and_swap_acquire((unsigned char*)&var, prev,
713 (unsigned char)val);
714 } while (curr != prev);
715 return (char)curr;
716 }
717 #endif // AO_HAVE_char_fetch_compare_and_swap_acquire
718
719 #ifdef AO_HAVE_char_fetch_compare_and_swap_acquire
720 //! Atomic compare-and-swap (acquire barrier).
721 static inline bool compare_exchange_acquire(
722 char& var, char& exp, char des) {
723 struct TypeCheck {
724 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
725 };
726 unsigned char old = AO_char_fetch_compare_and_swap_acquire(
727 (unsigned char*)&var, (unsigned char)exp, (unsigned char)des);
728 const bool ret = ((unsigned char)exp == old);
729 exp = (char)old;
730 return ret;
731 }
732 #endif // AO_HAVE_char_fetch_compare_and_swap_acquire
733
734 #ifdef AO_HAVE_char_fetch_and_add_acquire
735 //! Atomic fetch-add (acquire barrier).
736 static inline char fetch_add_acquire(char& var, char val) {
737 struct TypeCheck {
738 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
739 };
740 return (char)(
741 AO_char_fetch_and_add_acquire((unsigned char*)&var, (unsigned char)val));
742 }
743 #endif // AO_HAVE_char_fetch_and_add_acquire
744
745 #ifdef AO_HAVE_char_fetch_and_add_acquire
746 //! Atomic fetch-sub (acquire barrier).
747 static inline char fetch_sub_acquire(char& var, char val) {
748 struct TypeCheck {
749 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
750 };
751 return (char)(
752 AO_char_fetch_and_add_acquire((unsigned char*)&var, (unsigned char)-val));
753 }
754 #endif // AO_HAVE_char_fetch_and_add_acquire
755
756 #ifdef AO_HAVE_char_fetch_compare_and_swap_acquire
757 //! Atomic fetch-and (acquire barrier).
758 static inline char fetch_and_acquire(char& var, char val) {
759 struct TypeCheck {
760 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
761 };
762 unsigned char curr = AO_char_load((unsigned char*)&var);
763 unsigned char prev;
764 do {
765 prev = curr;
766 curr = AO_char_fetch_compare_and_swap_acquire((unsigned char*)&var, prev,
767 prev & (unsigned char)val);
768 } while (curr != prev);
769 return (char)curr;
770 }
771 #endif // AO_HAVE_char_fetch_compare_and_swap_acquire
772
773 #ifdef AO_HAVE_char_fetch_compare_and_swap_acquire
774 //! Atomic fetch-or (acquire barrier).
775 static inline char fetch_or_acquire(char& var, char val) {
776 struct TypeCheck {
777 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
778 };
779 unsigned char curr = AO_char_load((unsigned char*)&var);
780 unsigned char prev;
781 do {
782 prev = curr;
783 curr = AO_char_fetch_compare_and_swap_acquire((unsigned char*)&var, prev,
784 prev | (unsigned char)val);
785 } while (curr != prev);
786 return (char)curr;
787 }
788 #endif // AO_HAVE_char_fetch_compare_and_swap_acquire
789
790 #ifdef AO_HAVE_char_fetch_compare_and_swap_acquire
791 //! Atomic fetch-xor (acquire barrier).
792 static inline char fetch_xor_acquire(char& var, char val) {
793 struct TypeCheck {
794 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
795 };
796 unsigned char curr = AO_char_load((unsigned char*)&var);
797 unsigned char prev;
798 do {
799 prev = curr;
800 curr = AO_char_fetch_compare_and_swap_acquire((unsigned char*)&var, prev,
801 prev ^ (unsigned char)val);
802 } while (curr != prev);
803 return (char)curr;
804 }
805 #endif // AO_HAVE_char_fetch_compare_and_swap_acquire
806
807 #ifdef AO_HAVE_char_store_release
808 //! Atomic store (release barrier).
809 static inline void store_release(char& var, char val) {
810 struct TypeCheck {
811 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
812 };
813 AO_char_store_release((unsigned char*)&var, (unsigned char)val);
814 }
815 #endif // AO_HAVE_char_store_release
816
817 #ifdef AO_HAVE_char_fetch_compare_and_swap_release
818 //! Atomic exchange (release barrier).
819 static inline char exchange_release(char& var, char val) {
820 struct TypeCheck {
821 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
822 };
823 unsigned char curr = AO_char_load((unsigned char*)&var);
824 unsigned char prev;
825 do {
826 prev = curr;
827 curr = AO_char_fetch_compare_and_swap_release((unsigned char*)&var, prev,
828 (unsigned char)val);
829 } while (curr != prev);
830 return (char)curr;
831 }
832 #endif // AO_HAVE_char_fetch_compare_and_swap_release
833
834 #ifdef AO_HAVE_char_fetch_compare_and_swap_release
835 //! Atomic compare-and-swap (release barrier).
836 static inline bool compare_exchange_release(
837 char& var, char& exp, char des) {
838 struct TypeCheck {
839 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
840 };
841 unsigned char old = AO_char_fetch_compare_and_swap_release(
842 (unsigned char*)&var, (unsigned char)exp, (unsigned char)des);
843 const bool ret = ((unsigned char)exp == old);
844 exp = (char)old;
845 return ret;
846 }
847 #endif // AO_HAVE_char_fetch_compare_and_swap_release
848
849 #ifdef AO_HAVE_char_fetch_and_add_release
850 //! Atomic fetch-add (release barrier).
851 static inline char fetch_add_release(char& var, char val) {
852 struct TypeCheck {
853 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
854 };
855 return (char)(
856 AO_char_fetch_and_add_release((unsigned char*)&var, (unsigned char)val));
857 }
858 #endif // AO_HAVE_char_fetch_and_add_release
859
860 #ifdef AO_HAVE_char_fetch_and_add_release
861 //! Atomic fetch-sub (release barrier).
862 static inline char fetch_sub_release(char& var, char val) {
863 struct TypeCheck {
864 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
865 };
866 return (char)(
867 AO_char_fetch_and_add_release((unsigned char*)&var, (unsigned char)-val));
868 }
869 #endif // AO_HAVE_char_fetch_and_add_release
870
871 #ifdef AO_HAVE_char_fetch_compare_and_swap_release
872 //! Atomic fetch-and (release barrier).
873 static inline char fetch_and_release(char& var, char val) {
874 struct TypeCheck {
875 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
876 };
877 unsigned char curr = AO_char_load((unsigned char*)&var);
878 unsigned char prev;
879 do {
880 prev = curr;
881 curr = AO_char_fetch_compare_and_swap_release((unsigned char*)&var, prev,
882 prev & (unsigned char)val);
883 } while (curr != prev);
884 return (char)curr;
885 }
886 #endif // AO_HAVE_char_fetch_compare_and_swap_release
887
888 #ifdef AO_HAVE_char_fetch_compare_and_swap_release
889 //! Atomic fetch-or (release barrier).
890 static inline char fetch_or_release(char& var, char val) {
891 struct TypeCheck {
892 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
893 };
894 unsigned char curr = AO_char_load((unsigned char*)&var);
895 unsigned char prev;
896 do {
897 prev = curr;
898 curr = AO_char_fetch_compare_and_swap_release((unsigned char*)&var, prev,
899 prev | (unsigned char)val);
900 } while (curr != prev);
901 return (char)curr;
902 }
903 #endif // AO_HAVE_char_fetch_compare_and_swap_release
904
905 #ifdef AO_HAVE_char_fetch_compare_and_swap_release
906 //! Atomic fetch-xor (release barrier).
907 static inline char fetch_xor_release(char& var, char val) {
908 struct TypeCheck {
909 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
910 };
911 unsigned char curr = AO_char_load((unsigned char*)&var);
912 unsigned char prev;
913 do {
914 prev = curr;
915 curr = AO_char_fetch_compare_and_swap_release((unsigned char*)&var, prev,
916 prev ^ (unsigned char)val);
917 } while (curr != prev);
918 return (char)curr;
919 }
920 #endif // AO_HAVE_char_fetch_compare_and_swap_release
921
922 #ifdef AO_HAVE_char_fetch_compare_and_swap_full
923 //! Atomic exchange (acquire-release barrier).
924 static inline char exchange_acq_rel(char& var, char val) {
925 struct TypeCheck {
926 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
927 };
928 unsigned char curr = AO_char_load((unsigned char*)&var);
929 unsigned char prev;
930 do {
931 prev = curr;
932 curr = AO_char_fetch_compare_and_swap_full((unsigned char*)&var, prev,
933 (unsigned char)val);
934 } while (curr != prev);
935 return (char)curr;
936 }
937 #endif // AO_HAVE_char_fetch_compare_and_swap_full
938
939 #ifdef AO_HAVE_char_fetch_compare_and_swap_full
940 //! Atomic compare-and-swap (acquire-release barrier).
941 static inline bool compare_exchange_acq_rel(
942 char& var, char& exp, char des) {
943 struct TypeCheck {
944 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
945 };
946 unsigned char old = AO_char_fetch_compare_and_swap_full(
947 (unsigned char*)&var, (unsigned char)exp, (unsigned char)des);
948 const bool ret = ((unsigned char)exp == old);
949 exp = (char)old;
950 return ret;
951 }
952 #endif // AO_HAVE_char_fetch_compare_and_swap_full
953
954 #ifdef AO_HAVE_char_load_full
955 //! Atomic load (full barrier).
956 static inline char load_seq_cst(char const& var) {
957 struct TypeCheck {
958 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
959 };
960 return (char)AO_char_load_full((unsigned char const*)&var);
961 }
962 #endif // AO_HAVE_char_load_full
963
964 #ifdef AO_HAVE_char_store_full
965 //! Atomic store (full barrier).
966 static inline void store_seq_cst(char& var, char val) {
967 struct TypeCheck {
968 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
969 };
970 AO_char_store_full((unsigned char*)&var, (unsigned char)val);
971 }
972 #endif // AO_HAVE_char_store_full
973
974 #ifdef AO_HAVE_char_fetch_compare_and_swap
975 //! Atomic exchange (full barrier).
976 static inline char exchange_seq_cst(char& var, char val) {
977 struct TypeCheck {
978 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
979 };
980 AO_nop_full();
981 unsigned char curr = AO_char_load((unsigned char*)&var);
982 unsigned char prev;
983 do {
984 prev = curr;
985 curr = AO_char_fetch_compare_and_swap((unsigned char*)&var, prev,
986 (unsigned char)val);
987 AO_nop_full();
988 } while (curr != prev);
989 return (char)curr;
990 }
991 #endif // AO_HAVE_char_fetch_compare_and_swap
992
993 #ifdef AO_HAVE_char_fetch_compare_and_swap
994 //! Atomic compare-and-swap (full barrier).
995 static inline bool compare_exchange_seq_cst(
996 char& var, char& exp, char des) {
997 struct TypeCheck {
998 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
999 };
1000 AO_nop_full();
1001 unsigned char old = AO_char_fetch_compare_and_swap(
1002 (unsigned char*)&var, (unsigned char)exp, (unsigned char)des);
1003 const bool ret = ((unsigned char)exp == old);
1004 if (ret) {
1005 AO_nop_full();
1006 }
1007 exp = (char)old;
1008 return ret;
1009 }
1010 #endif // AO_HAVE_char_fetch_compare_and_swap
1011
1012 #ifdef AO_HAVE_char_fetch_and_add_full
1013 //! Atomic fetch-add (full barrier).
1014 static inline char fetch_add_seq_cst(char& var, char val) {
1015 struct TypeCheck {
1016 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
1017 };
1018 return (char)(
1019 AO_char_fetch_and_add_full((unsigned char*)&var, (unsigned char)val));
1020 }
1021 #endif // AO_HAVE_char_fetch_and_add_full
1022
1023 #ifdef AO_HAVE_char_fetch_and_add_full
1024 //! Atomic fetch-sub (full barrier).
1025 static inline char fetch_sub_seq_cst(char& var, char val) {
1026 struct TypeCheck {
1027 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
1028 };
1029 return (char)(
1030 AO_char_fetch_and_add_full((unsigned char*)&var, (unsigned char)-val));
1031 }
1032 #endif // AO_HAVE_char_fetch_and_add_full
1033
1034 #ifdef AO_HAVE_char_fetch_compare_and_swap_full
1035 //! Atomic fetch-and (full barrier).
1036 static inline char fetch_and_seq_cst(char& var, char val) {
1037 struct TypeCheck {
1038 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
1039 };
1040 AO_nop_full();
1041 unsigned char curr = AO_char_load((unsigned char*)&var);
1042 unsigned char prev;
1043 do {
1044 prev = curr;
1045 curr = AO_char_fetch_compare_and_swap((unsigned char*)&var, prev,
1046 prev & (unsigned char)val);
1047 AO_nop_full();
1048 } while (curr != prev);
1049 return (char)curr;
1050 }
1051 #endif // AO_HAVE_char_fetch_compare_and_swap_full
1052
1053 #ifdef AO_HAVE_char_fetch_compare_and_swap_full
1054 //! Atomic fetch-or (full barrier).
1055 static inline char fetch_or_seq_cst(char& var, char val) {
1056 struct TypeCheck {
1057 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
1058 };
1059 AO_nop_full();
1060 unsigned char curr = AO_char_load((unsigned char*)&var);
1061 unsigned char prev;
1062 do {
1063 prev = curr;
1064 curr = AO_char_fetch_compare_and_swap((unsigned char*)&var, prev,
1065 prev | (unsigned char)val);
1066 AO_nop_full();
1067 } while (curr != prev);
1068 return (char)curr;
1069 }
1070 #endif // AO_HAVE_char_fetch_compare_and_swap_full
1071
1072 #ifdef AO_HAVE_char_fetch_compare_and_swap_full
1073 //! Atomic fetch-xor (full barrier).
1074 static inline char fetch_xor_seq_cst(char& var, char val) {
1075 struct TypeCheck {
1076 int f : sizeof(char) == sizeof(unsigned char) ? 1 : -1;
1077 };
1078 AO_nop_full();
1079 unsigned char curr = AO_char_load((unsigned char*)&var);
1080 unsigned char prev;
1081 do {
1082 prev = curr;
1083 curr = AO_char_fetch_compare_and_swap((unsigned char*)&var, prev,
1084 prev ^ (unsigned char)val);
1085 AO_nop_full();
1086 } while (curr != prev);
1087 return (char)curr;
1088 }
1089 #endif // AO_HAVE_char_fetch_compare_and_swap_full
1090
1091 // overloads for unsigned short
1092
1093 #ifdef AO_HAVE_short_load
1094 //! Atomic load (no barrier).
1095 static inline unsigned short load_relaxed(unsigned short const& var) {
1096 struct TypeCheck {
1097 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1098 };
1099 return (unsigned short)AO_short_load((unsigned short const*)&var);
1100 }
1101 #endif // AO_HAVE_short_load
1102
1103 #ifdef AO_HAVE_short_store
1104 //! Atomic store (no barrier).
1105 static inline void store_relaxed(unsigned short& var, unsigned short val) {
1106 struct TypeCheck {
1107 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1108 };
1109 AO_short_store((unsigned short*)&var, (unsigned short)val);
1110 }
1111 #endif // AO_HAVE_short_store
1112
1113 #ifdef AO_HAVE_short_fetch_compare_and_swap
1114 //! Atomic exchange (no barrier).
1115 static inline unsigned short exchange_relaxed(unsigned short& var, unsigned short val) {
1116 struct TypeCheck {
1117 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1118 };
1119 unsigned short curr = AO_short_load((unsigned short*)&var);
1120 unsigned short prev;
1121 do {
1122 prev = curr;
1123 curr = AO_short_fetch_compare_and_swap((unsigned short*)&var, prev,
1124 (unsigned short)val);
1125 } while (curr != prev);
1126 return (unsigned short)curr;
1127 }
1128 #endif // AO_HAVE_short_fetch_compare_and_swap
1129
1130 #ifdef AO_HAVE_short_fetch_compare_and_swap
1131 //! Atomic compare-and-swap (no barrier).
1132 static inline bool compare_exchange_relaxed(
1133 unsigned short& var, unsigned short& exp, unsigned short des) {
1134 struct TypeCheck {
1135 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1136 };
1137 unsigned short old = AO_short_fetch_compare_and_swap(
1138 (unsigned short*)&var, (unsigned short)exp, (unsigned short)des);
1139 const bool ret = ((unsigned short)exp == old);
1140 exp = (unsigned short)old;
1141 return ret;
1142 }
1143 #endif // AO_HAVE_short_fetch_compare_and_swap
1144
1145 #ifdef AO_HAVE_short_fetch_and_add
1146 //! Atomic fetch-add (no barrier).
1147 static inline unsigned short fetch_add_relaxed(unsigned short& var, unsigned short val) {
1148 struct TypeCheck {
1149 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1150 };
1151 return (unsigned short)(
1152 AO_short_fetch_and_add((unsigned short*)&var, (unsigned short)val));
1153 }
1154 #endif // AO_HAVE_short_fetch_and_add
1155
1156 #ifdef AO_HAVE_short_fetch_and_add
1157 //! Atomic fetch-sub (no barrier).
1158 static inline unsigned short fetch_sub_relaxed(unsigned short& var, unsigned short val) {
1159 struct TypeCheck {
1160 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1161 };
1162 return (unsigned short)(
1163 AO_short_fetch_and_add((unsigned short*)&var, (unsigned short)-val));
1164 }
1165 #endif // AO_HAVE_short_fetch_and_add
1166
1167 #ifdef AO_HAVE_short_fetch_compare_and_swap
1168 //! Atomic fetch-and (no barrier).
1169 static inline unsigned short fetch_and_relaxed(unsigned short& var, unsigned short val) {
1170 struct TypeCheck {
1171 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1172 };
1173 unsigned short curr = AO_short_load((unsigned short*)&var);
1174 unsigned short prev;
1175 do {
1176 prev = curr;
1177 curr = AO_short_fetch_compare_and_swap((unsigned short*)&var, prev,
1178 prev & (unsigned short)val);
1179 } while (curr != prev);
1180 return (unsigned short)curr;
1181 }
1182 #endif // AO_HAVE_short_fetch_compare_and_swap
1183
1184 #ifdef AO_HAVE_short_fetch_compare_and_swap
1185 //! Atomic fetch-or (no barrier).
1186 static inline unsigned short fetch_or_relaxed(unsigned short& var, unsigned short val) {
1187 struct TypeCheck {
1188 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1189 };
1190 unsigned short curr = AO_short_load((unsigned short*)&var);
1191 unsigned short prev;
1192 do {
1193 prev = curr;
1194 curr = AO_short_fetch_compare_and_swap((unsigned short*)&var, prev,
1195 prev | (unsigned short)val);
1196 } while (curr != prev);
1197 return (unsigned short)curr;
1198 }
1199 #endif // AO_HAVE_short_fetch_compare_and_swap
1200
1201 #ifdef AO_HAVE_short_fetch_compare_and_swap
1202 //! Atomic fetch-xor (no barrier).
1203 static inline unsigned short fetch_xor_relaxed(unsigned short& var, unsigned short val) {
1204 struct TypeCheck {
1205 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1206 };
1207 unsigned short curr = AO_short_load((unsigned short*)&var);
1208 unsigned short prev;
1209 do {
1210 prev = curr;
1211 curr = AO_short_fetch_compare_and_swap((unsigned short*)&var, prev,
1212 prev ^ (unsigned short)val);
1213 } while (curr != prev);
1214 return (unsigned short)curr;
1215 }
1216 #endif // AO_HAVE_short_fetch_compare_and_swap
1217
1218 #ifdef AO_HAVE_short_load_acquire
1219 //! Atomic load (acquire barrier).
1220 static inline unsigned short load_acquire(unsigned short const& var) {
1221 struct TypeCheck {
1222 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1223 };
1224 return (unsigned short)AO_short_load_acquire((unsigned short const*)&var);
1225 }
1226 #endif // AO_HAVE_short_load_acquire
1227
1228 #ifdef AO_HAVE_short_fetch_compare_and_swap_acquire
1229 //! Atomic exchange (acquire barrier).
1230 static inline unsigned short exchange_acquire(unsigned short& var, unsigned short val) {
1231 struct TypeCheck {
1232 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1233 };
1234 unsigned short curr = AO_short_load((unsigned short*)&var);
1235 unsigned short prev;
1236 do {
1237 prev = curr;
1238 curr = AO_short_fetch_compare_and_swap_acquire((unsigned short*)&var, prev,
1239 (unsigned short)val);
1240 } while (curr != prev);
1241 return (unsigned short)curr;
1242 }
1243 #endif // AO_HAVE_short_fetch_compare_and_swap_acquire
1244
1245 #ifdef AO_HAVE_short_fetch_compare_and_swap_acquire
1246 //! Atomic compare-and-swap (acquire barrier).
1247 static inline bool compare_exchange_acquire(
1248 unsigned short& var, unsigned short& exp, unsigned short des) {
1249 struct TypeCheck {
1250 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1251 };
1252 unsigned short old = AO_short_fetch_compare_and_swap_acquire(
1253 (unsigned short*)&var, (unsigned short)exp, (unsigned short)des);
1254 const bool ret = ((unsigned short)exp == old);
1255 exp = (unsigned short)old;
1256 return ret;
1257 }
1258 #endif // AO_HAVE_short_fetch_compare_and_swap_acquire
1259
1260 #ifdef AO_HAVE_short_fetch_and_add_acquire
1261 //! Atomic fetch-add (acquire barrier).
1262 static inline unsigned short fetch_add_acquire(unsigned short& var, unsigned short val) {
1263 struct TypeCheck {
1264 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1265 };
1266 return (unsigned short)(
1267 AO_short_fetch_and_add_acquire((unsigned short*)&var, (unsigned short)val));
1268 }
1269 #endif // AO_HAVE_short_fetch_and_add_acquire
1270
1271 #ifdef AO_HAVE_short_fetch_and_add_acquire
1272 //! Atomic fetch-sub (acquire barrier).
1273 static inline unsigned short fetch_sub_acquire(unsigned short& var, unsigned short val) {
1274 struct TypeCheck {
1275 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1276 };
1277 return (unsigned short)(
1278 AO_short_fetch_and_add_acquire((unsigned short*)&var, (unsigned short)-val));
1279 }
1280 #endif // AO_HAVE_short_fetch_and_add_acquire
1281
1282 #ifdef AO_HAVE_short_fetch_compare_and_swap_acquire
1283 //! Atomic fetch-and (acquire barrier).
1284 static inline unsigned short fetch_and_acquire(unsigned short& var, unsigned short val) {
1285 struct TypeCheck {
1286 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1287 };
1288 unsigned short curr = AO_short_load((unsigned short*)&var);
1289 unsigned short prev;
1290 do {
1291 prev = curr;
1292 curr = AO_short_fetch_compare_and_swap_acquire((unsigned short*)&var, prev,
1293 prev & (unsigned short)val);
1294 } while (curr != prev);
1295 return (unsigned short)curr;
1296 }
1297 #endif // AO_HAVE_short_fetch_compare_and_swap_acquire
1298
1299 #ifdef AO_HAVE_short_fetch_compare_and_swap_acquire
1300 //! Atomic fetch-or (acquire barrier).
1301 static inline unsigned short fetch_or_acquire(unsigned short& var, unsigned short val) {
1302 struct TypeCheck {
1303 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1304 };
1305 unsigned short curr = AO_short_load((unsigned short*)&var);
1306 unsigned short prev;
1307 do {
1308 prev = curr;
1309 curr = AO_short_fetch_compare_and_swap_acquire((unsigned short*)&var, prev,
1310 prev | (unsigned short)val);
1311 } while (curr != prev);
1312 return (unsigned short)curr;
1313 }
1314 #endif // AO_HAVE_short_fetch_compare_and_swap_acquire
1315
1316 #ifdef AO_HAVE_short_fetch_compare_and_swap_acquire
1317 //! Atomic fetch-xor (acquire barrier).
1318 static inline unsigned short fetch_xor_acquire(unsigned short& var, unsigned short val) {
1319 struct TypeCheck {
1320 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1321 };
1322 unsigned short curr = AO_short_load((unsigned short*)&var);
1323 unsigned short prev;
1324 do {
1325 prev = curr;
1326 curr = AO_short_fetch_compare_and_swap_acquire((unsigned short*)&var, prev,
1327 prev ^ (unsigned short)val);
1328 } while (curr != prev);
1329 return (unsigned short)curr;
1330 }
1331 #endif // AO_HAVE_short_fetch_compare_and_swap_acquire
1332
1333 #ifdef AO_HAVE_short_store_release
1334 //! Atomic store (release barrier).
1335 static inline void store_release(unsigned short& var, unsigned short val) {
1336 struct TypeCheck {
1337 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1338 };
1339 AO_short_store_release((unsigned short*)&var, (unsigned short)val);
1340 }
1341 #endif // AO_HAVE_short_store_release
1342
1343 #ifdef AO_HAVE_short_fetch_compare_and_swap_release
1344 //! Atomic exchange (release barrier).
1345 static inline unsigned short exchange_release(unsigned short& var, unsigned short val) {
1346 struct TypeCheck {
1347 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1348 };
1349 unsigned short curr = AO_short_load((unsigned short*)&var);
1350 unsigned short prev;
1351 do {
1352 prev = curr;
1353 curr = AO_short_fetch_compare_and_swap_release((unsigned short*)&var, prev,
1354 (unsigned short)val);
1355 } while (curr != prev);
1356 return (unsigned short)curr;
1357 }
1358 #endif // AO_HAVE_short_fetch_compare_and_swap_release
1359
1360 #ifdef AO_HAVE_short_fetch_compare_and_swap_release
1361 //! Atomic compare-and-swap (release barrier).
1362 static inline bool compare_exchange_release(
1363 unsigned short& var, unsigned short& exp, unsigned short des) {
1364 struct TypeCheck {
1365 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1366 };
1367 unsigned short old = AO_short_fetch_compare_and_swap_release(
1368 (unsigned short*)&var, (unsigned short)exp, (unsigned short)des);
1369 const bool ret = ((unsigned short)exp == old);
1370 exp = (unsigned short)old;
1371 return ret;
1372 }
1373 #endif // AO_HAVE_short_fetch_compare_and_swap_release
1374
1375 #ifdef AO_HAVE_short_fetch_and_add_release
1376 //! Atomic fetch-add (release barrier).
1377 static inline unsigned short fetch_add_release(unsigned short& var, unsigned short val) {
1378 struct TypeCheck {
1379 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1380 };
1381 return (unsigned short)(
1382 AO_short_fetch_and_add_release((unsigned short*)&var, (unsigned short)val));
1383 }
1384 #endif // AO_HAVE_short_fetch_and_add_release
1385
1386 #ifdef AO_HAVE_short_fetch_and_add_release
1387 //! Atomic fetch-sub (release barrier).
1388 static inline unsigned short fetch_sub_release(unsigned short& var, unsigned short val) {
1389 struct TypeCheck {
1390 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1391 };
1392 return (unsigned short)(
1393 AO_short_fetch_and_add_release((unsigned short*)&var, (unsigned short)-val));
1394 }
1395 #endif // AO_HAVE_short_fetch_and_add_release
1396
1397 #ifdef AO_HAVE_short_fetch_compare_and_swap_release
1398 //! Atomic fetch-and (release barrier).
1399 static inline unsigned short fetch_and_release(unsigned short& var, unsigned short val) {
1400 struct TypeCheck {
1401 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1402 };
1403 unsigned short curr = AO_short_load((unsigned short*)&var);
1404 unsigned short prev;
1405 do {
1406 prev = curr;
1407 curr = AO_short_fetch_compare_and_swap_release((unsigned short*)&var, prev,
1408 prev & (unsigned short)val);
1409 } while (curr != prev);
1410 return (unsigned short)curr;
1411 }
1412 #endif // AO_HAVE_short_fetch_compare_and_swap_release
1413
1414 #ifdef AO_HAVE_short_fetch_compare_and_swap_release
1415 //! Atomic fetch-or (release barrier).
1416 static inline unsigned short fetch_or_release(unsigned short& var, unsigned short val) {
1417 struct TypeCheck {
1418 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1419 };
1420 unsigned short curr = AO_short_load((unsigned short*)&var);
1421 unsigned short prev;
1422 do {
1423 prev = curr;
1424 curr = AO_short_fetch_compare_and_swap_release((unsigned short*)&var, prev,
1425 prev | (unsigned short)val);
1426 } while (curr != prev);
1427 return (unsigned short)curr;
1428 }
1429 #endif // AO_HAVE_short_fetch_compare_and_swap_release
1430
1431 #ifdef AO_HAVE_short_fetch_compare_and_swap_release
1432 //! Atomic fetch-xor (release barrier).
1433 static inline unsigned short fetch_xor_release(unsigned short& var, unsigned short val) {
1434 struct TypeCheck {
1435 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1436 };
1437 unsigned short curr = AO_short_load((unsigned short*)&var);
1438 unsigned short prev;
1439 do {
1440 prev = curr;
1441 curr = AO_short_fetch_compare_and_swap_release((unsigned short*)&var, prev,
1442 prev ^ (unsigned short)val);
1443 } while (curr != prev);
1444 return (unsigned short)curr;
1445 }
1446 #endif // AO_HAVE_short_fetch_compare_and_swap_release
1447
1448 #ifdef AO_HAVE_short_fetch_compare_and_swap_full
1449 //! Atomic exchange (acquire-release barrier).
1450 static inline unsigned short exchange_acq_rel(unsigned short& var, unsigned short val) {
1451 struct TypeCheck {
1452 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1453 };
1454 unsigned short curr = AO_short_load((unsigned short*)&var);
1455 unsigned short prev;
1456 do {
1457 prev = curr;
1458 curr = AO_short_fetch_compare_and_swap_full((unsigned short*)&var, prev,
1459 (unsigned short)val);
1460 } while (curr != prev);
1461 return (unsigned short)curr;
1462 }
1463 #endif // AO_HAVE_short_fetch_compare_and_swap_full
1464
1465 #ifdef AO_HAVE_short_fetch_compare_and_swap_full
1466 //! Atomic compare-and-swap (acquire-release barrier).
1467 static inline bool compare_exchange_acq_rel(
1468 unsigned short& var, unsigned short& exp, unsigned short des) {
1469 struct TypeCheck {
1470 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1471 };
1472 unsigned short old = AO_short_fetch_compare_and_swap_full(
1473 (unsigned short*)&var, (unsigned short)exp, (unsigned short)des);
1474 const bool ret = ((unsigned short)exp == old);
1475 exp = (unsigned short)old;
1476 return ret;
1477 }
1478 #endif // AO_HAVE_short_fetch_compare_and_swap_full
1479
1480 #ifdef AO_HAVE_short_load_full
1481 //! Atomic load (full barrier).
1482 static inline unsigned short load_seq_cst(unsigned short const& var) {
1483 struct TypeCheck {
1484 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1485 };
1486 return (unsigned short)AO_short_load_full((unsigned short const*)&var);
1487 }
1488 #endif // AO_HAVE_short_load_full
1489
1490 #ifdef AO_HAVE_short_store_full
1491 //! Atomic store (full barrier).
1492 static inline void store_seq_cst(unsigned short& var, unsigned short val) {
1493 struct TypeCheck {
1494 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1495 };
1496 AO_short_store_full((unsigned short*)&var, (unsigned short)val);
1497 }
1498 #endif // AO_HAVE_short_store_full
1499
1500 #ifdef AO_HAVE_short_fetch_compare_and_swap
1501 //! Atomic exchange (full barrier).
1502 static inline unsigned short exchange_seq_cst(unsigned short& var, unsigned short val) {
1503 struct TypeCheck {
1504 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1505 };
1506 AO_nop_full();
1507 unsigned short curr = AO_short_load((unsigned short*)&var);
1508 unsigned short prev;
1509 do {
1510 prev = curr;
1511 curr = AO_short_fetch_compare_and_swap((unsigned short*)&var, prev,
1512 (unsigned short)val);
1513 AO_nop_full();
1514 } while (curr != prev);
1515 return (unsigned short)curr;
1516 }
1517 #endif // AO_HAVE_short_fetch_compare_and_swap
1518
1519 #ifdef AO_HAVE_short_fetch_compare_and_swap
1520 //! Atomic compare-and-swap (full barrier).
1521 static inline bool compare_exchange_seq_cst(
1522 unsigned short& var, unsigned short& exp, unsigned short des) {
1523 struct TypeCheck {
1524 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1525 };
1526 AO_nop_full();
1527 unsigned short old = AO_short_fetch_compare_and_swap(
1528 (unsigned short*)&var, (unsigned short)exp, (unsigned short)des);
1529 const bool ret = ((unsigned short)exp == old);
1530 if (ret) {
1531 AO_nop_full();
1532 }
1533 exp = (unsigned short)old;
1534 return ret;
1535 }
1536 #endif // AO_HAVE_short_fetch_compare_and_swap
1537
1538 #ifdef AO_HAVE_short_fetch_and_add_full
1539 //! Atomic fetch-add (full barrier).
1540 static inline unsigned short fetch_add_seq_cst(unsigned short& var, unsigned short val) {
1541 struct TypeCheck {
1542 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1543 };
1544 return (unsigned short)(
1545 AO_short_fetch_and_add_full((unsigned short*)&var, (unsigned short)val));
1546 }
1547 #endif // AO_HAVE_short_fetch_and_add_full
1548
1549 #ifdef AO_HAVE_short_fetch_and_add_full
1550 //! Atomic fetch-sub (full barrier).
1551 static inline unsigned short fetch_sub_seq_cst(unsigned short& var, unsigned short val) {
1552 struct TypeCheck {
1553 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1554 };
1555 return (unsigned short)(
1556 AO_short_fetch_and_add_full((unsigned short*)&var, (unsigned short)-val));
1557 }
1558 #endif // AO_HAVE_short_fetch_and_add_full
1559
1560 #ifdef AO_HAVE_short_fetch_compare_and_swap_full
1561 //! Atomic fetch-and (full barrier).
1562 static inline unsigned short fetch_and_seq_cst(unsigned short& var, unsigned short val) {
1563 struct TypeCheck {
1564 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1565 };
1566 AO_nop_full();
1567 unsigned short curr = AO_short_load((unsigned short*)&var);
1568 unsigned short prev;
1569 do {
1570 prev = curr;
1571 curr = AO_short_fetch_compare_and_swap((unsigned short*)&var, prev,
1572 prev & (unsigned short)val);
1573 AO_nop_full();
1574 } while (curr != prev);
1575 return (unsigned short)curr;
1576 }
1577 #endif // AO_HAVE_short_fetch_compare_and_swap_full
1578
1579 #ifdef AO_HAVE_short_fetch_compare_and_swap_full
1580 //! Atomic fetch-or (full barrier).
1581 static inline unsigned short fetch_or_seq_cst(unsigned short& var, unsigned short val) {
1582 struct TypeCheck {
1583 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1584 };
1585 AO_nop_full();
1586 unsigned short curr = AO_short_load((unsigned short*)&var);
1587 unsigned short prev;
1588 do {
1589 prev = curr;
1590 curr = AO_short_fetch_compare_and_swap((unsigned short*)&var, prev,
1591 prev | (unsigned short)val);
1592 AO_nop_full();
1593 } while (curr != prev);
1594 return (unsigned short)curr;
1595 }
1596 #endif // AO_HAVE_short_fetch_compare_and_swap_full
1597
1598 #ifdef AO_HAVE_short_fetch_compare_and_swap_full
1599 //! Atomic fetch-xor (full barrier).
1600 static inline unsigned short fetch_xor_seq_cst(unsigned short& var, unsigned short val) {
1601 struct TypeCheck {
1602 int f : sizeof(unsigned short) == sizeof(unsigned short) ? 1 : -1;
1603 };
1604 AO_nop_full();
1605 unsigned short curr = AO_short_load((unsigned short*)&var);
1606 unsigned short prev;
1607 do {
1608 prev = curr;
1609 curr = AO_short_fetch_compare_and_swap((unsigned short*)&var, prev,
1610 prev ^ (unsigned short)val);
1611 AO_nop_full();
1612 } while (curr != prev);
1613 return (unsigned short)curr;
1614 }
1615 #endif // AO_HAVE_short_fetch_compare_and_swap_full
1616
1617 // overloads for short
1618
1619 #ifdef AO_HAVE_short_load
1620 //! Atomic load (no barrier).
1621 static inline short load_relaxed(short const& var) {
1622 struct TypeCheck {
1623 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1624 };
1625 return (short)AO_short_load((unsigned short const*)&var);
1626 }
1627 #endif // AO_HAVE_short_load
1628
1629 #ifdef AO_HAVE_short_store
1630 //! Atomic store (no barrier).
1631 static inline void store_relaxed(short& var, short val) {
1632 struct TypeCheck {
1633 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1634 };
1635 AO_short_store((unsigned short*)&var, (unsigned short)val);
1636 }
1637 #endif // AO_HAVE_short_store
1638
1639 #ifdef AO_HAVE_short_fetch_compare_and_swap
1640 //! Atomic exchange (no barrier).
1641 static inline short exchange_relaxed(short& var, short val) {
1642 struct TypeCheck {
1643 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1644 };
1645 unsigned short curr = AO_short_load((unsigned short*)&var);
1646 unsigned short prev;
1647 do {
1648 prev = curr;
1649 curr = AO_short_fetch_compare_and_swap((unsigned short*)&var, prev,
1650 (unsigned short)val);
1651 } while (curr != prev);
1652 return (short)curr;
1653 }
1654 #endif // AO_HAVE_short_fetch_compare_and_swap
1655
1656 #ifdef AO_HAVE_short_fetch_compare_and_swap
1657 //! Atomic compare-and-swap (no barrier).
1658 static inline bool compare_exchange_relaxed(
1659 short& var, short& exp, short des) {
1660 struct TypeCheck {
1661 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1662 };
1663 unsigned short old = AO_short_fetch_compare_and_swap(
1664 (unsigned short*)&var, (unsigned short)exp, (unsigned short)des);
1665 const bool ret = ((unsigned short)exp == old);
1666 exp = (short)old;
1667 return ret;
1668 }
1669 #endif // AO_HAVE_short_fetch_compare_and_swap
1670
1671 #ifdef AO_HAVE_short_fetch_and_add
1672 //! Atomic fetch-add (no barrier).
1673 static inline short fetch_add_relaxed(short& var, short val) {
1674 struct TypeCheck {
1675 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1676 };
1677 return (short)(
1678 AO_short_fetch_and_add((unsigned short*)&var, (unsigned short)val));
1679 }
1680 #endif // AO_HAVE_short_fetch_and_add
1681
1682 #ifdef AO_HAVE_short_fetch_and_add
1683 //! Atomic fetch-sub (no barrier).
1684 static inline short fetch_sub_relaxed(short& var, short val) {
1685 struct TypeCheck {
1686 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1687 };
1688 return (short)(
1689 AO_short_fetch_and_add((unsigned short*)&var, (unsigned short)-val));
1690 }
1691 #endif // AO_HAVE_short_fetch_and_add
1692
1693 #ifdef AO_HAVE_short_fetch_compare_and_swap
1694 //! Atomic fetch-and (no barrier).
1695 static inline short fetch_and_relaxed(short& var, short val) {
1696 struct TypeCheck {
1697 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1698 };
1699 unsigned short curr = AO_short_load((unsigned short*)&var);
1700 unsigned short prev;
1701 do {
1702 prev = curr;
1703 curr = AO_short_fetch_compare_and_swap((unsigned short*)&var, prev,
1704 prev & (unsigned short)val);
1705 } while (curr != prev);
1706 return (short)curr;
1707 }
1708 #endif // AO_HAVE_short_fetch_compare_and_swap
1709
1710 #ifdef AO_HAVE_short_fetch_compare_and_swap
1711 //! Atomic fetch-or (no barrier).
1712 static inline short fetch_or_relaxed(short& var, short val) {
1713 struct TypeCheck {
1714 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1715 };
1716 unsigned short curr = AO_short_load((unsigned short*)&var);
1717 unsigned short prev;
1718 do {
1719 prev = curr;
1720 curr = AO_short_fetch_compare_and_swap((unsigned short*)&var, prev,
1721 prev | (unsigned short)val);
1722 } while (curr != prev);
1723 return (short)curr;
1724 }
1725 #endif // AO_HAVE_short_fetch_compare_and_swap
1726
1727 #ifdef AO_HAVE_short_fetch_compare_and_swap
1728 //! Atomic fetch-xor (no barrier).
1729 static inline short fetch_xor_relaxed(short& var, short val) {
1730 struct TypeCheck {
1731 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1732 };
1733 unsigned short curr = AO_short_load((unsigned short*)&var);
1734 unsigned short prev;
1735 do {
1736 prev = curr;
1737 curr = AO_short_fetch_compare_and_swap((unsigned short*)&var, prev,
1738 prev ^ (unsigned short)val);
1739 } while (curr != prev);
1740 return (short)curr;
1741 }
1742 #endif // AO_HAVE_short_fetch_compare_and_swap
1743
1744 #ifdef AO_HAVE_short_load_acquire
1745 //! Atomic load (acquire barrier).
1746 static inline short load_acquire(short const& var) {
1747 struct TypeCheck {
1748 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1749 };
1750 return (short)AO_short_load_acquire((unsigned short const*)&var);
1751 }
1752 #endif // AO_HAVE_short_load_acquire
1753
1754 #ifdef AO_HAVE_short_fetch_compare_and_swap_acquire
1755 //! Atomic exchange (acquire barrier).
1756 static inline short exchange_acquire(short& var, short val) {
1757 struct TypeCheck {
1758 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1759 };
1760 unsigned short curr = AO_short_load((unsigned short*)&var);
1761 unsigned short prev;
1762 do {
1763 prev = curr;
1764 curr = AO_short_fetch_compare_and_swap_acquire((unsigned short*)&var, prev,
1765 (unsigned short)val);
1766 } while (curr != prev);
1767 return (short)curr;
1768 }
1769 #endif // AO_HAVE_short_fetch_compare_and_swap_acquire
1770
1771 #ifdef AO_HAVE_short_fetch_compare_and_swap_acquire
1772 //! Atomic compare-and-swap (acquire barrier).
1773 static inline bool compare_exchange_acquire(
1774 short& var, short& exp, short des) {
1775 struct TypeCheck {
1776 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1777 };
1778 unsigned short old = AO_short_fetch_compare_and_swap_acquire(
1779 (unsigned short*)&var, (unsigned short)exp, (unsigned short)des);
1780 const bool ret = ((unsigned short)exp == old);
1781 exp = (short)old;
1782 return ret;
1783 }
1784 #endif // AO_HAVE_short_fetch_compare_and_swap_acquire
1785
1786 #ifdef AO_HAVE_short_fetch_and_add_acquire
1787 //! Atomic fetch-add (acquire barrier).
1788 static inline short fetch_add_acquire(short& var, short val) {
1789 struct TypeCheck {
1790 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1791 };
1792 return (short)(
1793 AO_short_fetch_and_add_acquire((unsigned short*)&var, (unsigned short)val));
1794 }
1795 #endif // AO_HAVE_short_fetch_and_add_acquire
1796
1797 #ifdef AO_HAVE_short_fetch_and_add_acquire
1798 //! Atomic fetch-sub (acquire barrier).
1799 static inline short fetch_sub_acquire(short& var, short val) {
1800 struct TypeCheck {
1801 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1802 };
1803 return (short)(
1804 AO_short_fetch_and_add_acquire((unsigned short*)&var, (unsigned short)-val));
1805 }
1806 #endif // AO_HAVE_short_fetch_and_add_acquire
1807
1808 #ifdef AO_HAVE_short_fetch_compare_and_swap_acquire
1809 //! Atomic fetch-and (acquire barrier).
1810 static inline short fetch_and_acquire(short& var, short val) {
1811 struct TypeCheck {
1812 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1813 };
1814 unsigned short curr = AO_short_load((unsigned short*)&var);
1815 unsigned short prev;
1816 do {
1817 prev = curr;
1818 curr = AO_short_fetch_compare_and_swap_acquire((unsigned short*)&var, prev,
1819 prev & (unsigned short)val);
1820 } while (curr != prev);
1821 return (short)curr;
1822 }
1823 #endif // AO_HAVE_short_fetch_compare_and_swap_acquire
1824
1825 #ifdef AO_HAVE_short_fetch_compare_and_swap_acquire
1826 //! Atomic fetch-or (acquire barrier).
1827 static inline short fetch_or_acquire(short& var, short val) {
1828 struct TypeCheck {
1829 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1830 };
1831 unsigned short curr = AO_short_load((unsigned short*)&var);
1832 unsigned short prev;
1833 do {
1834 prev = curr;
1835 curr = AO_short_fetch_compare_and_swap_acquire((unsigned short*)&var, prev,
1836 prev | (unsigned short)val);
1837 } while (curr != prev);
1838 return (short)curr;
1839 }
1840 #endif // AO_HAVE_short_fetch_compare_and_swap_acquire
1841
1842 #ifdef AO_HAVE_short_fetch_compare_and_swap_acquire
1843 //! Atomic fetch-xor (acquire barrier).
1844 static inline short fetch_xor_acquire(short& var, short val) {
1845 struct TypeCheck {
1846 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1847 };
1848 unsigned short curr = AO_short_load((unsigned short*)&var);
1849 unsigned short prev;
1850 do {
1851 prev = curr;
1852 curr = AO_short_fetch_compare_and_swap_acquire((unsigned short*)&var, prev,
1853 prev ^ (unsigned short)val);
1854 } while (curr != prev);
1855 return (short)curr;
1856 }
1857 #endif // AO_HAVE_short_fetch_compare_and_swap_acquire
1858
1859 #ifdef AO_HAVE_short_store_release
1860 //! Atomic store (release barrier).
1861 static inline void store_release(short& var, short val) {
1862 struct TypeCheck {
1863 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1864 };
1865 AO_short_store_release((unsigned short*)&var, (unsigned short)val);
1866 }
1867 #endif // AO_HAVE_short_store_release
1868
1869 #ifdef AO_HAVE_short_fetch_compare_and_swap_release
1870 //! Atomic exchange (release barrier).
1871 static inline short exchange_release(short& var, short val) {
1872 struct TypeCheck {
1873 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1874 };
1875 unsigned short curr = AO_short_load((unsigned short*)&var);
1876 unsigned short prev;
1877 do {
1878 prev = curr;
1879 curr = AO_short_fetch_compare_and_swap_release((unsigned short*)&var, prev,
1880 (unsigned short)val);
1881 } while (curr != prev);
1882 return (short)curr;
1883 }
1884 #endif // AO_HAVE_short_fetch_compare_and_swap_release
1885
1886 #ifdef AO_HAVE_short_fetch_compare_and_swap_release
1887 //! Atomic compare-and-swap (release barrier).
1888 static inline bool compare_exchange_release(
1889 short& var, short& exp, short des) {
1890 struct TypeCheck {
1891 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1892 };
1893 unsigned short old = AO_short_fetch_compare_and_swap_release(
1894 (unsigned short*)&var, (unsigned short)exp, (unsigned short)des);
1895 const bool ret = ((unsigned short)exp == old);
1896 exp = (short)old;
1897 return ret;
1898 }
1899 #endif // AO_HAVE_short_fetch_compare_and_swap_release
1900
1901 #ifdef AO_HAVE_short_fetch_and_add_release
1902 //! Atomic fetch-add (release barrier).
1903 static inline short fetch_add_release(short& var, short val) {
1904 struct TypeCheck {
1905 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1906 };
1907 return (short)(
1908 AO_short_fetch_and_add_release((unsigned short*)&var, (unsigned short)val));
1909 }
1910 #endif // AO_HAVE_short_fetch_and_add_release
1911
1912 #ifdef AO_HAVE_short_fetch_and_add_release
1913 //! Atomic fetch-sub (release barrier).
1914 static inline short fetch_sub_release(short& var, short val) {
1915 struct TypeCheck {
1916 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1917 };
1918 return (short)(
1919 AO_short_fetch_and_add_release((unsigned short*)&var, (unsigned short)-val));
1920 }
1921 #endif // AO_HAVE_short_fetch_and_add_release
1922
1923 #ifdef AO_HAVE_short_fetch_compare_and_swap_release
1924 //! Atomic fetch-and (release barrier).
1925 static inline short fetch_and_release(short& var, short val) {
1926 struct TypeCheck {
1927 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1928 };
1929 unsigned short curr = AO_short_load((unsigned short*)&var);
1930 unsigned short prev;
1931 do {
1932 prev = curr;
1933 curr = AO_short_fetch_compare_and_swap_release((unsigned short*)&var, prev,
1934 prev & (unsigned short)val);
1935 } while (curr != prev);
1936 return (short)curr;
1937 }
1938 #endif // AO_HAVE_short_fetch_compare_and_swap_release
1939
1940 #ifdef AO_HAVE_short_fetch_compare_and_swap_release
1941 //! Atomic fetch-or (release barrier).
1942 static inline short fetch_or_release(short& var, short val) {
1943 struct TypeCheck {
1944 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1945 };
1946 unsigned short curr = AO_short_load((unsigned short*)&var);
1947 unsigned short prev;
1948 do {
1949 prev = curr;
1950 curr = AO_short_fetch_compare_and_swap_release((unsigned short*)&var, prev,
1951 prev | (unsigned short)val);
1952 } while (curr != prev);
1953 return (short)curr;
1954 }
1955 #endif // AO_HAVE_short_fetch_compare_and_swap_release
1956
1957 #ifdef AO_HAVE_short_fetch_compare_and_swap_release
1958 //! Atomic fetch-xor (release barrier).
1959 static inline short fetch_xor_release(short& var, short val) {
1960 struct TypeCheck {
1961 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1962 };
1963 unsigned short curr = AO_short_load((unsigned short*)&var);
1964 unsigned short prev;
1965 do {
1966 prev = curr;
1967 curr = AO_short_fetch_compare_and_swap_release((unsigned short*)&var, prev,
1968 prev ^ (unsigned short)val);
1969 } while (curr != prev);
1970 return (short)curr;
1971 }
1972 #endif // AO_HAVE_short_fetch_compare_and_swap_release
1973
1974 #ifdef AO_HAVE_short_fetch_compare_and_swap_full
1975 //! Atomic exchange (acquire-release barrier).
1976 static inline short exchange_acq_rel(short& var, short val) {
1977 struct TypeCheck {
1978 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1979 };
1980 unsigned short curr = AO_short_load((unsigned short*)&var);
1981 unsigned short prev;
1982 do {
1983 prev = curr;
1984 curr = AO_short_fetch_compare_and_swap_full((unsigned short*)&var, prev,
1985 (unsigned short)val);
1986 } while (curr != prev);
1987 return (short)curr;
1988 }
1989 #endif // AO_HAVE_short_fetch_compare_and_swap_full
1990
1991 #ifdef AO_HAVE_short_fetch_compare_and_swap_full
1992 //! Atomic compare-and-swap (acquire-release barrier).
1993 static inline bool compare_exchange_acq_rel(
1994 short& var, short& exp, short des) {
1995 struct TypeCheck {
1996 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
1997 };
1998 unsigned short old = AO_short_fetch_compare_and_swap_full(
1999 (unsigned short*)&var, (unsigned short)exp, (unsigned short)des);
2000 const bool ret = ((unsigned short)exp == old);
2001 exp = (short)old;
2002 return ret;
2003 }
2004 #endif // AO_HAVE_short_fetch_compare_and_swap_full
2005
2006 #ifdef AO_HAVE_short_load_full
2007 //! Atomic load (full barrier).
2008 static inline short load_seq_cst(short const& var) {
2009 struct TypeCheck {
2010 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
2011 };
2012 return (short)AO_short_load_full((unsigned short const*)&var);
2013 }
2014 #endif // AO_HAVE_short_load_full
2015
2016 #ifdef AO_HAVE_short_store_full
2017 //! Atomic store (full barrier).
2018 static inline void store_seq_cst(short& var, short val) {
2019 struct TypeCheck {
2020 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
2021 };
2022 AO_short_store_full((unsigned short*)&var, (unsigned short)val);
2023 }
2024 #endif // AO_HAVE_short_store_full
2025
2026 #ifdef AO_HAVE_short_fetch_compare_and_swap
2027 //! Atomic exchange (full barrier).
2028 static inline short exchange_seq_cst(short& var, short val) {
2029 struct TypeCheck {
2030 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
2031 };
2032 AO_nop_full();
2033 unsigned short curr = AO_short_load((unsigned short*)&var);
2034 unsigned short prev;
2035 do {
2036 prev = curr;
2037 curr = AO_short_fetch_compare_and_swap((unsigned short*)&var, prev,
2038 (unsigned short)val);
2039 AO_nop_full();
2040 } while (curr != prev);
2041 return (short)curr;
2042 }
2043 #endif // AO_HAVE_short_fetch_compare_and_swap
2044
2045 #ifdef AO_HAVE_short_fetch_compare_and_swap
2046 //! Atomic compare-and-swap (full barrier).
2047 static inline bool compare_exchange_seq_cst(
2048 short& var, short& exp, short des) {
2049 struct TypeCheck {
2050 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
2051 };
2052 AO_nop_full();
2053 unsigned short old = AO_short_fetch_compare_and_swap(
2054 (unsigned short*)&var, (unsigned short)exp, (unsigned short)des);
2055 const bool ret = ((unsigned short)exp == old);
2056 if (ret) {
2057 AO_nop_full();
2058 }
2059 exp = (short)old;
2060 return ret;
2061 }
2062 #endif // AO_HAVE_short_fetch_compare_and_swap
2063
2064 #ifdef AO_HAVE_short_fetch_and_add_full
2065 //! Atomic fetch-add (full barrier).
2066 static inline short fetch_add_seq_cst(short& var, short val) {
2067 struct TypeCheck {
2068 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
2069 };
2070 return (short)(
2071 AO_short_fetch_and_add_full((unsigned short*)&var, (unsigned short)val));
2072 }
2073 #endif // AO_HAVE_short_fetch_and_add_full
2074
2075 #ifdef AO_HAVE_short_fetch_and_add_full
2076 //! Atomic fetch-sub (full barrier).
2077 static inline short fetch_sub_seq_cst(short& var, short val) {
2078 struct TypeCheck {
2079 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
2080 };
2081 return (short)(
2082 AO_short_fetch_and_add_full((unsigned short*)&var, (unsigned short)-val));
2083 }
2084 #endif // AO_HAVE_short_fetch_and_add_full
2085
2086 #ifdef AO_HAVE_short_fetch_compare_and_swap_full
2087 //! Atomic fetch-and (full barrier).
2088 static inline short fetch_and_seq_cst(short& var, short val) {
2089 struct TypeCheck {
2090 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
2091 };
2092 AO_nop_full();
2093 unsigned short curr = AO_short_load((unsigned short*)&var);
2094 unsigned short prev;
2095 do {
2096 prev = curr;
2097 curr = AO_short_fetch_compare_and_swap((unsigned short*)&var, prev,
2098 prev & (unsigned short)val);
2099 AO_nop_full();
2100 } while (curr != prev);
2101 return (short)curr;
2102 }
2103 #endif // AO_HAVE_short_fetch_compare_and_swap_full
2104
2105 #ifdef AO_HAVE_short_fetch_compare_and_swap_full
2106 //! Atomic fetch-or (full barrier).
2107 static inline short fetch_or_seq_cst(short& var, short val) {
2108 struct TypeCheck {
2109 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
2110 };
2111 AO_nop_full();
2112 unsigned short curr = AO_short_load((unsigned short*)&var);
2113 unsigned short prev;
2114 do {
2115 prev = curr;
2116 curr = AO_short_fetch_compare_and_swap((unsigned short*)&var, prev,
2117 prev | (unsigned short)val);
2118 AO_nop_full();
2119 } while (curr != prev);
2120 return (short)curr;
2121 }
2122 #endif // AO_HAVE_short_fetch_compare_and_swap_full
2123
2124 #ifdef AO_HAVE_short_fetch_compare_and_swap_full
2125 //! Atomic fetch-xor (full barrier).
2126 static inline short fetch_xor_seq_cst(short& var, short val) {
2127 struct TypeCheck {
2128 int f : sizeof(short) == sizeof(unsigned short) ? 1 : -1;
2129 };
2130 AO_nop_full();
2131 unsigned short curr = AO_short_load((unsigned short*)&var);
2132 unsigned short prev;
2133 do {
2134 prev = curr;
2135 curr = AO_short_fetch_compare_and_swap((unsigned short*)&var, prev,
2136 prev ^ (unsigned short)val);
2137 AO_nop_full();
2138 } while (curr != prev);
2139 return (short)curr;
2140 }
2141 #endif // AO_HAVE_short_fetch_compare_and_swap_full
2142
2143#ifndef AO_T_IS_INT
2144
2145 // overloads for unsigned int
2146
2147 #ifdef AO_HAVE_int_load
2148 //! Atomic load (no barrier).
2149 static inline unsigned int load_relaxed(unsigned int const& var) {
2150 struct TypeCheck {
2151 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2152 };
2153 return (unsigned int)AO_int_load((unsigned int const*)&var);
2154 }
2155 #endif // AO_HAVE_int_load
2156
2157 #ifdef AO_HAVE_int_store
2158 //! Atomic store (no barrier).
2159 static inline void store_relaxed(unsigned int& var, unsigned int val) {
2160 struct TypeCheck {
2161 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2162 };
2163 AO_int_store((unsigned int*)&var, (unsigned int)val);
2164 }
2165 #endif // AO_HAVE_int_store
2166
2167 #ifdef AO_HAVE_int_fetch_compare_and_swap
2168 //! Atomic exchange (no barrier).
2169 static inline unsigned int exchange_relaxed(unsigned int& var, unsigned int val) {
2170 struct TypeCheck {
2171 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2172 };
2173 unsigned int curr = AO_int_load((unsigned int*)&var);
2174 unsigned int prev;
2175 do {
2176 prev = curr;
2177 curr = AO_int_fetch_compare_and_swap((unsigned int*)&var, prev,
2178 (unsigned int)val);
2179 } while (curr != prev);
2180 return (unsigned int)curr;
2181 }
2182 #endif // AO_HAVE_int_fetch_compare_and_swap
2183
2184 #ifdef AO_HAVE_int_fetch_compare_and_swap
2185 //! Atomic compare-and-swap (no barrier).
2186 static inline bool compare_exchange_relaxed(
2187 unsigned int& var, unsigned int& exp, unsigned int des) {
2188 struct TypeCheck {
2189 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2190 };
2191 unsigned int old = AO_int_fetch_compare_and_swap(
2192 (unsigned int*)&var, (unsigned int)exp, (unsigned int)des);
2193 const bool ret = ((unsigned int)exp == old);
2194 exp = (unsigned int)old;
2195 return ret;
2196 }
2197 #endif // AO_HAVE_int_fetch_compare_and_swap
2198
2199 #ifdef AO_HAVE_int_fetch_and_add
2200 //! Atomic fetch-add (no barrier).
2201 static inline unsigned int fetch_add_relaxed(unsigned int& var, unsigned int val) {
2202 struct TypeCheck {
2203 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2204 };
2205 return (unsigned int)(
2206 AO_int_fetch_and_add((unsigned int*)&var, (unsigned int)val));
2207 }
2208 #endif // AO_HAVE_int_fetch_and_add
2209
2210 #ifdef AO_HAVE_int_fetch_and_add
2211 //! Atomic fetch-sub (no barrier).
2212 static inline unsigned int fetch_sub_relaxed(unsigned int& var, unsigned int val) {
2213 struct TypeCheck {
2214 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2215 };
2216 return (unsigned int)(
2217 AO_int_fetch_and_add((unsigned int*)&var, (unsigned int)-val));
2218 }
2219 #endif // AO_HAVE_int_fetch_and_add
2220
2221 #ifdef AO_HAVE_int_fetch_compare_and_swap
2222 //! Atomic fetch-and (no barrier).
2223 static inline unsigned int fetch_and_relaxed(unsigned int& var, unsigned int val) {
2224 struct TypeCheck {
2225 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2226 };
2227 unsigned int curr = AO_int_load((unsigned int*)&var);
2228 unsigned int prev;
2229 do {
2230 prev = curr;
2231 curr = AO_int_fetch_compare_and_swap((unsigned int*)&var, prev,
2232 prev & (unsigned int)val);
2233 } while (curr != prev);
2234 return (unsigned int)curr;
2235 }
2236 #endif // AO_HAVE_int_fetch_compare_and_swap
2237
2238 #ifdef AO_HAVE_int_fetch_compare_and_swap
2239 //! Atomic fetch-or (no barrier).
2240 static inline unsigned int fetch_or_relaxed(unsigned int& var, unsigned int val) {
2241 struct TypeCheck {
2242 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2243 };
2244 unsigned int curr = AO_int_load((unsigned int*)&var);
2245 unsigned int prev;
2246 do {
2247 prev = curr;
2248 curr = AO_int_fetch_compare_and_swap((unsigned int*)&var, prev,
2249 prev | (unsigned int)val);
2250 } while (curr != prev);
2251 return (unsigned int)curr;
2252 }
2253 #endif // AO_HAVE_int_fetch_compare_and_swap
2254
2255 #ifdef AO_HAVE_int_fetch_compare_and_swap
2256 //! Atomic fetch-xor (no barrier).
2257 static inline unsigned int fetch_xor_relaxed(unsigned int& var, unsigned int val) {
2258 struct TypeCheck {
2259 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2260 };
2261 unsigned int curr = AO_int_load((unsigned int*)&var);
2262 unsigned int prev;
2263 do {
2264 prev = curr;
2265 curr = AO_int_fetch_compare_and_swap((unsigned int*)&var, prev,
2266 prev ^ (unsigned int)val);
2267 } while (curr != prev);
2268 return (unsigned int)curr;
2269 }
2270 #endif // AO_HAVE_int_fetch_compare_and_swap
2271
2272 #ifdef AO_HAVE_int_load_acquire
2273 //! Atomic load (acquire barrier).
2274 static inline unsigned int load_acquire(unsigned int const& var) {
2275 struct TypeCheck {
2276 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2277 };
2278 return (unsigned int)AO_int_load_acquire((unsigned int const*)&var);
2279 }
2280 #endif // AO_HAVE_int_load_acquire
2281
2282 #ifdef AO_HAVE_int_fetch_compare_and_swap_acquire
2283 //! Atomic exchange (acquire barrier).
2284 static inline unsigned int exchange_acquire(unsigned int& var, unsigned int val) {
2285 struct TypeCheck {
2286 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2287 };
2288 unsigned int curr = AO_int_load((unsigned int*)&var);
2289 unsigned int prev;
2290 do {
2291 prev = curr;
2292 curr = AO_int_fetch_compare_and_swap_acquire((unsigned int*)&var, prev,
2293 (unsigned int)val);
2294 } while (curr != prev);
2295 return (unsigned int)curr;
2296 }
2297 #endif // AO_HAVE_int_fetch_compare_and_swap_acquire
2298
2299 #ifdef AO_HAVE_int_fetch_compare_and_swap_acquire
2300 //! Atomic compare-and-swap (acquire barrier).
2301 static inline bool compare_exchange_acquire(
2302 unsigned int& var, unsigned int& exp, unsigned int des) {
2303 struct TypeCheck {
2304 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2305 };
2306 unsigned int old = AO_int_fetch_compare_and_swap_acquire(
2307 (unsigned int*)&var, (unsigned int)exp, (unsigned int)des);
2308 const bool ret = ((unsigned int)exp == old);
2309 exp = (unsigned int)old;
2310 return ret;
2311 }
2312 #endif // AO_HAVE_int_fetch_compare_and_swap_acquire
2313
2314 #ifdef AO_HAVE_int_fetch_and_add_acquire
2315 //! Atomic fetch-add (acquire barrier).
2316 static inline unsigned int fetch_add_acquire(unsigned int& var, unsigned int val) {
2317 struct TypeCheck {
2318 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2319 };
2320 return (unsigned int)(
2321 AO_int_fetch_and_add_acquire((unsigned int*)&var, (unsigned int)val));
2322 }
2323 #endif // AO_HAVE_int_fetch_and_add_acquire
2324
2325 #ifdef AO_HAVE_int_fetch_and_add_acquire
2326 //! Atomic fetch-sub (acquire barrier).
2327 static inline unsigned int fetch_sub_acquire(unsigned int& var, unsigned int val) {
2328 struct TypeCheck {
2329 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2330 };
2331 return (unsigned int)(
2332 AO_int_fetch_and_add_acquire((unsigned int*)&var, (unsigned int)-val));
2333 }
2334 #endif // AO_HAVE_int_fetch_and_add_acquire
2335
2336 #ifdef AO_HAVE_int_fetch_compare_and_swap_acquire
2337 //! Atomic fetch-and (acquire barrier).
2338 static inline unsigned int fetch_and_acquire(unsigned int& var, unsigned int val) {
2339 struct TypeCheck {
2340 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2341 };
2342 unsigned int curr = AO_int_load((unsigned int*)&var);
2343 unsigned int prev;
2344 do {
2345 prev = curr;
2346 curr = AO_int_fetch_compare_and_swap_acquire((unsigned int*)&var, prev,
2347 prev & (unsigned int)val);
2348 } while (curr != prev);
2349 return (unsigned int)curr;
2350 }
2351 #endif // AO_HAVE_int_fetch_compare_and_swap_acquire
2352
2353 #ifdef AO_HAVE_int_fetch_compare_and_swap_acquire
2354 //! Atomic fetch-or (acquire barrier).
2355 static inline unsigned int fetch_or_acquire(unsigned int& var, unsigned int val) {
2356 struct TypeCheck {
2357 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2358 };
2359 unsigned int curr = AO_int_load((unsigned int*)&var);
2360 unsigned int prev;
2361 do {
2362 prev = curr;
2363 curr = AO_int_fetch_compare_and_swap_acquire((unsigned int*)&var, prev,
2364 prev | (unsigned int)val);
2365 } while (curr != prev);
2366 return (unsigned int)curr;
2367 }
2368 #endif // AO_HAVE_int_fetch_compare_and_swap_acquire
2369
2370 #ifdef AO_HAVE_int_fetch_compare_and_swap_acquire
2371 //! Atomic fetch-xor (acquire barrier).
2372 static inline unsigned int fetch_xor_acquire(unsigned int& var, unsigned int val) {
2373 struct TypeCheck {
2374 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2375 };
2376 unsigned int curr = AO_int_load((unsigned int*)&var);
2377 unsigned int prev;
2378 do {
2379 prev = curr;
2380 curr = AO_int_fetch_compare_and_swap_acquire((unsigned int*)&var, prev,
2381 prev ^ (unsigned int)val);
2382 } while (curr != prev);
2383 return (unsigned int)curr;
2384 }
2385 #endif // AO_HAVE_int_fetch_compare_and_swap_acquire
2386
2387 #ifdef AO_HAVE_int_store_release
2388 //! Atomic store (release barrier).
2389 static inline void store_release(unsigned int& var, unsigned int val) {
2390 struct TypeCheck {
2391 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2392 };
2393 AO_int_store_release((unsigned int*)&var, (unsigned int)val);
2394 }
2395 #endif // AO_HAVE_int_store_release
2396
2397 #ifdef AO_HAVE_int_fetch_compare_and_swap_release
2398 //! Atomic exchange (release barrier).
2399 static inline unsigned int exchange_release(unsigned int& var, unsigned int val) {
2400 struct TypeCheck {
2401 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2402 };
2403 unsigned int curr = AO_int_load((unsigned int*)&var);
2404 unsigned int prev;
2405 do {
2406 prev = curr;
2407 curr = AO_int_fetch_compare_and_swap_release((unsigned int*)&var, prev,
2408 (unsigned int)val);
2409 } while (curr != prev);
2410 return (unsigned int)curr;
2411 }
2412 #endif // AO_HAVE_int_fetch_compare_and_swap_release
2413
2414 #ifdef AO_HAVE_int_fetch_compare_and_swap_release
2415 //! Atomic compare-and-swap (release barrier).
2416 static inline bool compare_exchange_release(
2417 unsigned int& var, unsigned int& exp, unsigned int des) {
2418 struct TypeCheck {
2419 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2420 };
2421 unsigned int old = AO_int_fetch_compare_and_swap_release(
2422 (unsigned int*)&var, (unsigned int)exp, (unsigned int)des);
2423 const bool ret = ((unsigned int)exp == old);
2424 exp = (unsigned int)old;
2425 return ret;
2426 }
2427 #endif // AO_HAVE_int_fetch_compare_and_swap_release
2428
2429 #ifdef AO_HAVE_int_fetch_and_add_release
2430 //! Atomic fetch-add (release barrier).
2431 static inline unsigned int fetch_add_release(unsigned int& var, unsigned int val) {
2432 struct TypeCheck {
2433 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2434 };
2435 return (unsigned int)(
2436 AO_int_fetch_and_add_release((unsigned int*)&var, (unsigned int)val));
2437 }
2438 #endif // AO_HAVE_int_fetch_and_add_release
2439
2440 #ifdef AO_HAVE_int_fetch_and_add_release
2441 //! Atomic fetch-sub (release barrier).
2442 static inline unsigned int fetch_sub_release(unsigned int& var, unsigned int val) {
2443 struct TypeCheck {
2444 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2445 };
2446 return (unsigned int)(
2447 AO_int_fetch_and_add_release((unsigned int*)&var, (unsigned int)-val));
2448 }
2449 #endif // AO_HAVE_int_fetch_and_add_release
2450
2451 #ifdef AO_HAVE_int_fetch_compare_and_swap_release
2452 //! Atomic fetch-and (release barrier).
2453 static inline unsigned int fetch_and_release(unsigned int& var, unsigned int val) {
2454 struct TypeCheck {
2455 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2456 };
2457 unsigned int curr = AO_int_load((unsigned int*)&var);
2458 unsigned int prev;
2459 do {
2460 prev = curr;
2461 curr = AO_int_fetch_compare_and_swap_release((unsigned int*)&var, prev,
2462 prev & (unsigned int)val);
2463 } while (curr != prev);
2464 return (unsigned int)curr;
2465 }
2466 #endif // AO_HAVE_int_fetch_compare_and_swap_release
2467
2468 #ifdef AO_HAVE_int_fetch_compare_and_swap_release
2469 //! Atomic fetch-or (release barrier).
2470 static inline unsigned int fetch_or_release(unsigned int& var, unsigned int val) {
2471 struct TypeCheck {
2472 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2473 };
2474 unsigned int curr = AO_int_load((unsigned int*)&var);
2475 unsigned int prev;
2476 do {
2477 prev = curr;
2478 curr = AO_int_fetch_compare_and_swap_release((unsigned int*)&var, prev,
2479 prev | (unsigned int)val);
2480 } while (curr != prev);
2481 return (unsigned int)curr;
2482 }
2483 #endif // AO_HAVE_int_fetch_compare_and_swap_release
2484
2485 #ifdef AO_HAVE_int_fetch_compare_and_swap_release
2486 //! Atomic fetch-xor (release barrier).
2487 static inline unsigned int fetch_xor_release(unsigned int& var, unsigned int val) {
2488 struct TypeCheck {
2489 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2490 };
2491 unsigned int curr = AO_int_load((unsigned int*)&var);
2492 unsigned int prev;
2493 do {
2494 prev = curr;
2495 curr = AO_int_fetch_compare_and_swap_release((unsigned int*)&var, prev,
2496 prev ^ (unsigned int)val);
2497 } while (curr != prev);
2498 return (unsigned int)curr;
2499 }
2500 #endif // AO_HAVE_int_fetch_compare_and_swap_release
2501
2502 #ifdef AO_HAVE_int_fetch_compare_and_swap_full
2503 //! Atomic exchange (acquire-release barrier).
2504 static inline unsigned int exchange_acq_rel(unsigned int& var, unsigned int val) {
2505 struct TypeCheck {
2506 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2507 };
2508 unsigned int curr = AO_int_load((unsigned int*)&var);
2509 unsigned int prev;
2510 do {
2511 prev = curr;
2512 curr = AO_int_fetch_compare_and_swap_full((unsigned int*)&var, prev,
2513 (unsigned int)val);
2514 } while (curr != prev);
2515 return (unsigned int)curr;
2516 }
2517 #endif // AO_HAVE_int_fetch_compare_and_swap_full
2518
2519 #ifdef AO_HAVE_int_fetch_compare_and_swap_full
2520 //! Atomic compare-and-swap (acquire-release barrier).
2521 static inline bool compare_exchange_acq_rel(
2522 unsigned int& var, unsigned int& exp, unsigned int des) {
2523 struct TypeCheck {
2524 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2525 };
2526 unsigned int old = AO_int_fetch_compare_and_swap_full(
2527 (unsigned int*)&var, (unsigned int)exp, (unsigned int)des);
2528 const bool ret = ((unsigned int)exp == old);
2529 exp = (unsigned int)old;
2530 return ret;
2531 }
2532 #endif // AO_HAVE_int_fetch_compare_and_swap_full
2533
2534 #ifdef AO_HAVE_int_load_full
2535 //! Atomic load (full barrier).
2536 static inline unsigned int load_seq_cst(unsigned int const& var) {
2537 struct TypeCheck {
2538 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2539 };
2540 return (unsigned int)AO_int_load_full((unsigned int const*)&var);
2541 }
2542 #endif // AO_HAVE_int_load_full
2543
2544 #ifdef AO_HAVE_int_store_full
2545 //! Atomic store (full barrier).
2546 static inline void store_seq_cst(unsigned int& var, unsigned int val) {
2547 struct TypeCheck {
2548 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2549 };
2550 AO_int_store_full((unsigned int*)&var, (unsigned int)val);
2551 }
2552 #endif // AO_HAVE_int_store_full
2553
2554 #ifdef AO_HAVE_int_fetch_compare_and_swap
2555 //! Atomic exchange (full barrier).
2556 static inline unsigned int exchange_seq_cst(unsigned int& var, unsigned int val) {
2557 struct TypeCheck {
2558 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2559 };
2560 AO_nop_full();
2561 unsigned int curr = AO_int_load((unsigned int*)&var);
2562 unsigned int prev;
2563 do {
2564 prev = curr;
2565 curr = AO_int_fetch_compare_and_swap((unsigned int*)&var, prev,
2566 (unsigned int)val);
2567 AO_nop_full();
2568 } while (curr != prev);
2569 return (unsigned int)curr;
2570 }
2571 #endif // AO_HAVE_int_fetch_compare_and_swap
2572
2573 #ifdef AO_HAVE_int_fetch_compare_and_swap
2574 //! Atomic compare-and-swap (full barrier).
2575 static inline bool compare_exchange_seq_cst(
2576 unsigned int& var, unsigned int& exp, unsigned int des) {
2577 struct TypeCheck {
2578 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2579 };
2580 AO_nop_full();
2581 unsigned int old = AO_int_fetch_compare_and_swap(
2582 (unsigned int*)&var, (unsigned int)exp, (unsigned int)des);
2583 const bool ret = ((unsigned int)exp == old);
2584 if (ret) {
2585 AO_nop_full();
2586 }
2587 exp = (unsigned int)old;
2588 return ret;
2589 }
2590 #endif // AO_HAVE_int_fetch_compare_and_swap
2591
2592 #ifdef AO_HAVE_int_fetch_and_add_full
2593 //! Atomic fetch-add (full barrier).
2594 static inline unsigned int fetch_add_seq_cst(unsigned int& var, unsigned int val) {
2595 struct TypeCheck {
2596 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2597 };
2598 return (unsigned int)(
2599 AO_int_fetch_and_add_full((unsigned int*)&var, (unsigned int)val));
2600 }
2601 #endif // AO_HAVE_int_fetch_and_add_full
2602
2603 #ifdef AO_HAVE_int_fetch_and_add_full
2604 //! Atomic fetch-sub (full barrier).
2605 static inline unsigned int fetch_sub_seq_cst(unsigned int& var, unsigned int val) {
2606 struct TypeCheck {
2607 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2608 };
2609 return (unsigned int)(
2610 AO_int_fetch_and_add_full((unsigned int*)&var, (unsigned int)-val));
2611 }
2612 #endif // AO_HAVE_int_fetch_and_add_full
2613
2614 #ifdef AO_HAVE_int_fetch_compare_and_swap_full
2615 //! Atomic fetch-and (full barrier).
2616 static inline unsigned int fetch_and_seq_cst(unsigned int& var, unsigned int val) {
2617 struct TypeCheck {
2618 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2619 };
2620 AO_nop_full();
2621 unsigned int curr = AO_int_load((unsigned int*)&var);
2622 unsigned int prev;
2623 do {
2624 prev = curr;
2625 curr = AO_int_fetch_compare_and_swap((unsigned int*)&var, prev,
2626 prev & (unsigned int)val);
2627 AO_nop_full();
2628 } while (curr != prev);
2629 return (unsigned int)curr;
2630 }
2631 #endif // AO_HAVE_int_fetch_compare_and_swap_full
2632
2633 #ifdef AO_HAVE_int_fetch_compare_and_swap_full
2634 //! Atomic fetch-or (full barrier).
2635 static inline unsigned int fetch_or_seq_cst(unsigned int& var, unsigned int val) {
2636 struct TypeCheck {
2637 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2638 };
2639 AO_nop_full();
2640 unsigned int curr = AO_int_load((unsigned int*)&var);
2641 unsigned int prev;
2642 do {
2643 prev = curr;
2644 curr = AO_int_fetch_compare_and_swap((unsigned int*)&var, prev,
2645 prev | (unsigned int)val);
2646 AO_nop_full();
2647 } while (curr != prev);
2648 return (unsigned int)curr;
2649 }
2650 #endif // AO_HAVE_int_fetch_compare_and_swap_full
2651
2652 #ifdef AO_HAVE_int_fetch_compare_and_swap_full
2653 //! Atomic fetch-xor (full barrier).
2654 static inline unsigned int fetch_xor_seq_cst(unsigned int& var, unsigned int val) {
2655 struct TypeCheck {
2656 int f : sizeof(unsigned int) == sizeof(unsigned int) ? 1 : -1;
2657 };
2658 AO_nop_full();
2659 unsigned int curr = AO_int_load((unsigned int*)&var);
2660 unsigned int prev;
2661 do {
2662 prev = curr;
2663 curr = AO_int_fetch_compare_and_swap((unsigned int*)&var, prev,
2664 prev ^ (unsigned int)val);
2665 AO_nop_full();
2666 } while (curr != prev);
2667 return (unsigned int)curr;
2668 }
2669 #endif // AO_HAVE_int_fetch_compare_and_swap_full
2670
2671 // overloads for int
2672
2673 #ifdef AO_HAVE_int_load
2674 //! Atomic load (no barrier).
2675 static inline int load_relaxed(int const& var) {
2676 struct TypeCheck {
2677 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2678 };
2679 return (int)AO_int_load((unsigned int const*)&var);
2680 }
2681 #endif // AO_HAVE_int_load
2682
2683 #ifdef AO_HAVE_int_store
2684 //! Atomic store (no barrier).
2685 static inline void store_relaxed(int& var, int val) {
2686 struct TypeCheck {
2687 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2688 };
2689 AO_int_store((unsigned int*)&var, (unsigned int)val);
2690 }
2691 #endif // AO_HAVE_int_store
2692
2693 #ifdef AO_HAVE_int_fetch_compare_and_swap
2694 //! Atomic exchange (no barrier).
2695 static inline int exchange_relaxed(int& var, int val) {
2696 struct TypeCheck {
2697 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2698 };
2699 unsigned int curr = AO_int_load((unsigned int*)&var);
2700 unsigned int prev;
2701 do {
2702 prev = curr;
2703 curr = AO_int_fetch_compare_and_swap((unsigned int*)&var, prev,
2704 (unsigned int)val);
2705 } while (curr != prev);
2706 return (int)curr;
2707 }
2708 #endif // AO_HAVE_int_fetch_compare_and_swap
2709
2710 #ifdef AO_HAVE_int_fetch_compare_and_swap
2711 //! Atomic compare-and-swap (no barrier).
2712 static inline bool compare_exchange_relaxed(
2713 int& var, int& exp, int des) {
2714 struct TypeCheck {
2715 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2716 };
2717 unsigned int old = AO_int_fetch_compare_and_swap(
2718 (unsigned int*)&var, (unsigned int)exp, (unsigned int)des);
2719 const bool ret = ((unsigned int)exp == old);
2720 exp = (int)old;
2721 return ret;
2722 }
2723 #endif // AO_HAVE_int_fetch_compare_and_swap
2724
2725 #ifdef AO_HAVE_int_fetch_and_add
2726 //! Atomic fetch-add (no barrier).
2727 static inline int fetch_add_relaxed(int& var, int val) {
2728 struct TypeCheck {
2729 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2730 };
2731 return (int)(
2732 AO_int_fetch_and_add((unsigned int*)&var, (unsigned int)val));
2733 }
2734 #endif // AO_HAVE_int_fetch_and_add
2735
2736 #ifdef AO_HAVE_int_fetch_and_add
2737 //! Atomic fetch-sub (no barrier).
2738 static inline int fetch_sub_relaxed(int& var, int val) {
2739 struct TypeCheck {
2740 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2741 };
2742 return (int)(
2743 AO_int_fetch_and_add((unsigned int*)&var, (unsigned int)-val));
2744 }
2745 #endif // AO_HAVE_int_fetch_and_add
2746
2747 #ifdef AO_HAVE_int_fetch_compare_and_swap
2748 //! Atomic fetch-and (no barrier).
2749 static inline int fetch_and_relaxed(int& var, int val) {
2750 struct TypeCheck {
2751 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2752 };
2753 unsigned int curr = AO_int_load((unsigned int*)&var);
2754 unsigned int prev;
2755 do {
2756 prev = curr;
2757 curr = AO_int_fetch_compare_and_swap((unsigned int*)&var, prev,
2758 prev & (unsigned int)val);
2759 } while (curr != prev);
2760 return (int)curr;
2761 }
2762 #endif // AO_HAVE_int_fetch_compare_and_swap
2763
2764 #ifdef AO_HAVE_int_fetch_compare_and_swap
2765 //! Atomic fetch-or (no barrier).
2766 static inline int fetch_or_relaxed(int& var, int val) {
2767 struct TypeCheck {
2768 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2769 };
2770 unsigned int curr = AO_int_load((unsigned int*)&var);
2771 unsigned int prev;
2772 do {
2773 prev = curr;
2774 curr = AO_int_fetch_compare_and_swap((unsigned int*)&var, prev,
2775 prev | (unsigned int)val);
2776 } while (curr != prev);
2777 return (int)curr;
2778 }
2779 #endif // AO_HAVE_int_fetch_compare_and_swap
2780
2781 #ifdef AO_HAVE_int_fetch_compare_and_swap
2782 //! Atomic fetch-xor (no barrier).
2783 static inline int fetch_xor_relaxed(int& var, int val) {
2784 struct TypeCheck {
2785 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2786 };
2787 unsigned int curr = AO_int_load((unsigned int*)&var);
2788 unsigned int prev;
2789 do {
2790 prev = curr;
2791 curr = AO_int_fetch_compare_and_swap((unsigned int*)&var, prev,
2792 prev ^ (unsigned int)val);
2793 } while (curr != prev);
2794 return (int)curr;
2795 }
2796 #endif // AO_HAVE_int_fetch_compare_and_swap
2797
2798 #ifdef AO_HAVE_int_load_acquire
2799 //! Atomic load (acquire barrier).
2800 static inline int load_acquire(int const& var) {
2801 struct TypeCheck {
2802 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2803 };
2804 return (int)AO_int_load_acquire((unsigned int const*)&var);
2805 }
2806 #endif // AO_HAVE_int_load_acquire
2807
2808 #ifdef AO_HAVE_int_fetch_compare_and_swap_acquire
2809 //! Atomic exchange (acquire barrier).
2810 static inline int exchange_acquire(int& var, int val) {
2811 struct TypeCheck {
2812 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2813 };
2814 unsigned int curr = AO_int_load((unsigned int*)&var);
2815 unsigned int prev;
2816 do {
2817 prev = curr;
2818 curr = AO_int_fetch_compare_and_swap_acquire((unsigned int*)&var, prev,
2819 (unsigned int)val);
2820 } while (curr != prev);
2821 return (int)curr;
2822 }
2823 #endif // AO_HAVE_int_fetch_compare_and_swap_acquire
2824
2825 #ifdef AO_HAVE_int_fetch_compare_and_swap_acquire
2826 //! Atomic compare-and-swap (acquire barrier).
2827 static inline bool compare_exchange_acquire(
2828 int& var, int& exp, int des) {
2829 struct TypeCheck {
2830 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2831 };
2832 unsigned int old = AO_int_fetch_compare_and_swap_acquire(
2833 (unsigned int*)&var, (unsigned int)exp, (unsigned int)des);
2834 const bool ret = ((unsigned int)exp == old);
2835 exp = (int)old;
2836 return ret;
2837 }
2838 #endif // AO_HAVE_int_fetch_compare_and_swap_acquire
2839
2840 #ifdef AO_HAVE_int_fetch_and_add_acquire
2841 //! Atomic fetch-add (acquire barrier).
2842 static inline int fetch_add_acquire(int& var, int val) {
2843 struct TypeCheck {
2844 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2845 };
2846 return (int)(
2847 AO_int_fetch_and_add_acquire((unsigned int*)&var, (unsigned int)val));
2848 }
2849 #endif // AO_HAVE_int_fetch_and_add_acquire
2850
2851 #ifdef AO_HAVE_int_fetch_and_add_acquire
2852 //! Atomic fetch-sub (acquire barrier).
2853 static inline int fetch_sub_acquire(int& var, int val) {
2854 struct TypeCheck {
2855 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2856 };
2857 return (int)(
2858 AO_int_fetch_and_add_acquire((unsigned int*)&var, (unsigned int)-val));
2859 }
2860 #endif // AO_HAVE_int_fetch_and_add_acquire
2861
2862 #ifdef AO_HAVE_int_fetch_compare_and_swap_acquire
2863 //! Atomic fetch-and (acquire barrier).
2864 static inline int fetch_and_acquire(int& var, int val) {
2865 struct TypeCheck {
2866 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2867 };
2868 unsigned int curr = AO_int_load((unsigned int*)&var);
2869 unsigned int prev;
2870 do {
2871 prev = curr;
2872 curr = AO_int_fetch_compare_and_swap_acquire((unsigned int*)&var, prev,
2873 prev & (unsigned int)val);
2874 } while (curr != prev);
2875 return (int)curr;
2876 }
2877 #endif // AO_HAVE_int_fetch_compare_and_swap_acquire
2878
2879 #ifdef AO_HAVE_int_fetch_compare_and_swap_acquire
2880 //! Atomic fetch-or (acquire barrier).
2881 static inline int fetch_or_acquire(int& var, int val) {
2882 struct TypeCheck {
2883 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2884 };
2885 unsigned int curr = AO_int_load((unsigned int*)&var);
2886 unsigned int prev;
2887 do {
2888 prev = curr;
2889 curr = AO_int_fetch_compare_and_swap_acquire((unsigned int*)&var, prev,
2890 prev | (unsigned int)val);
2891 } while (curr != prev);
2892 return (int)curr;
2893 }
2894 #endif // AO_HAVE_int_fetch_compare_and_swap_acquire
2895
2896 #ifdef AO_HAVE_int_fetch_compare_and_swap_acquire
2897 //! Atomic fetch-xor (acquire barrier).
2898 static inline int fetch_xor_acquire(int& var, int val) {
2899 struct TypeCheck {
2900 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2901 };
2902 unsigned int curr = AO_int_load((unsigned int*)&var);
2903 unsigned int prev;
2904 do {
2905 prev = curr;
2906 curr = AO_int_fetch_compare_and_swap_acquire((unsigned int*)&var, prev,
2907 prev ^ (unsigned int)val);
2908 } while (curr != prev);
2909 return (int)curr;
2910 }
2911 #endif // AO_HAVE_int_fetch_compare_and_swap_acquire
2912
2913 #ifdef AO_HAVE_int_store_release
2914 //! Atomic store (release barrier).
2915 static inline void store_release(int& var, int val) {
2916 struct TypeCheck {
2917 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2918 };
2919 AO_int_store_release((unsigned int*)&var, (unsigned int)val);
2920 }
2921 #endif // AO_HAVE_int_store_release
2922
2923 #ifdef AO_HAVE_int_fetch_compare_and_swap_release
2924 //! Atomic exchange (release barrier).
2925 static inline int exchange_release(int& var, int val) {
2926 struct TypeCheck {
2927 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2928 };
2929 unsigned int curr = AO_int_load((unsigned int*)&var);
2930 unsigned int prev;
2931 do {
2932 prev = curr;
2933 curr = AO_int_fetch_compare_and_swap_release((unsigned int*)&var, prev,
2934 (unsigned int)val);
2935 } while (curr != prev);
2936 return (int)curr;
2937 }
2938 #endif // AO_HAVE_int_fetch_compare_and_swap_release
2939
2940 #ifdef AO_HAVE_int_fetch_compare_and_swap_release
2941 //! Atomic compare-and-swap (release barrier).
2942 static inline bool compare_exchange_release(
2943 int& var, int& exp, int des) {
2944 struct TypeCheck {
2945 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2946 };
2947 unsigned int old = AO_int_fetch_compare_and_swap_release(
2948 (unsigned int*)&var, (unsigned int)exp, (unsigned int)des);
2949 const bool ret = ((unsigned int)exp == old);
2950 exp = (int)old;
2951 return ret;
2952 }
2953 #endif // AO_HAVE_int_fetch_compare_and_swap_release
2954
2955 #ifdef AO_HAVE_int_fetch_and_add_release
2956 //! Atomic fetch-add (release barrier).
2957 static inline int fetch_add_release(int& var, int val) {
2958 struct TypeCheck {
2959 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2960 };
2961 return (int)(
2962 AO_int_fetch_and_add_release((unsigned int*)&var, (unsigned int)val));
2963 }
2964 #endif // AO_HAVE_int_fetch_and_add_release
2965
2966 #ifdef AO_HAVE_int_fetch_and_add_release
2967 //! Atomic fetch-sub (release barrier).
2968 static inline int fetch_sub_release(int& var, int val) {
2969 struct TypeCheck {
2970 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2971 };
2972 return (int)(
2973 AO_int_fetch_and_add_release((unsigned int*)&var, (unsigned int)-val));
2974 }
2975 #endif // AO_HAVE_int_fetch_and_add_release
2976
2977 #ifdef AO_HAVE_int_fetch_compare_and_swap_release
2978 //! Atomic fetch-and (release barrier).
2979 static inline int fetch_and_release(int& var, int val) {
2980 struct TypeCheck {
2981 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2982 };
2983 unsigned int curr = AO_int_load((unsigned int*)&var);
2984 unsigned int prev;
2985 do {
2986 prev = curr;
2987 curr = AO_int_fetch_compare_and_swap_release((unsigned int*)&var, prev,
2988 prev & (unsigned int)val);
2989 } while (curr != prev);
2990 return (int)curr;
2991 }
2992 #endif // AO_HAVE_int_fetch_compare_and_swap_release
2993
2994 #ifdef AO_HAVE_int_fetch_compare_and_swap_release
2995 //! Atomic fetch-or (release barrier).
2996 static inline int fetch_or_release(int& var, int val) {
2997 struct TypeCheck {
2998 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
2999 };
3000 unsigned int curr = AO_int_load((unsigned int*)&var);
3001 unsigned int prev;
3002 do {
3003 prev = curr;
3004 curr = AO_int_fetch_compare_and_swap_release((unsigned int*)&var, prev,
3005 prev | (unsigned int)val);
3006 } while (curr != prev);
3007 return (int)curr;
3008 }
3009 #endif // AO_HAVE_int_fetch_compare_and_swap_release
3010
3011 #ifdef AO_HAVE_int_fetch_compare_and_swap_release
3012 //! Atomic fetch-xor (release barrier).
3013 static inline int fetch_xor_release(int& var, int val) {
3014 struct TypeCheck {
3015 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
3016 };
3017 unsigned int curr = AO_int_load((unsigned int*)&var);
3018 unsigned int prev;
3019 do {
3020 prev = curr;
3021 curr = AO_int_fetch_compare_and_swap_release((unsigned int*)&var, prev,
3022 prev ^ (unsigned int)val);
3023 } while (curr != prev);
3024 return (int)curr;
3025 }
3026 #endif // AO_HAVE_int_fetch_compare_and_swap_release
3027
3028 #ifdef AO_HAVE_int_fetch_compare_and_swap_full
3029 //! Atomic exchange (acquire-release barrier).
3030 static inline int exchange_acq_rel(int& var, int val) {
3031 struct TypeCheck {
3032 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
3033 };
3034 unsigned int curr = AO_int_load((unsigned int*)&var);
3035 unsigned int prev;
3036 do {
3037 prev = curr;
3038 curr = AO_int_fetch_compare_and_swap_full((unsigned int*)&var, prev,
3039 (unsigned int)val);
3040 } while (curr != prev);
3041 return (int)curr;
3042 }
3043 #endif // AO_HAVE_int_fetch_compare_and_swap_full
3044
3045 #ifdef AO_HAVE_int_fetch_compare_and_swap_full
3046 //! Atomic compare-and-swap (acquire-release barrier).
3047 static inline bool compare_exchange_acq_rel(
3048 int& var, int& exp, int des) {
3049 struct TypeCheck {
3050 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
3051 };
3052 unsigned int old = AO_int_fetch_compare_and_swap_full(
3053 (unsigned int*)&var, (unsigned int)exp, (unsigned int)des);
3054 const bool ret = ((unsigned int)exp == old);
3055 exp = (int)old;
3056 return ret;
3057 }
3058 #endif // AO_HAVE_int_fetch_compare_and_swap_full
3059
3060 #ifdef AO_HAVE_int_load_full
3061 //! Atomic load (full barrier).
3062 static inline int load_seq_cst(int const& var) {
3063 struct TypeCheck {
3064 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
3065 };
3066 return (int)AO_int_load_full((unsigned int const*)&var);
3067 }
3068 #endif // AO_HAVE_int_load_full
3069
3070 #ifdef AO_HAVE_int_store_full
3071 //! Atomic store (full barrier).
3072 static inline void store_seq_cst(int& var, int val) {
3073 struct TypeCheck {
3074 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
3075 };
3076 AO_int_store_full((unsigned int*)&var, (unsigned int)val);
3077 }
3078 #endif // AO_HAVE_int_store_full
3079
3080 #ifdef AO_HAVE_int_fetch_compare_and_swap
3081 //! Atomic exchange (full barrier).
3082 static inline int exchange_seq_cst(int& var, int val) {
3083 struct TypeCheck {
3084 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
3085 };
3086 AO_nop_full();
3087 unsigned int curr = AO_int_load((unsigned int*)&var);
3088 unsigned int prev;
3089 do {
3090 prev = curr;
3091 curr = AO_int_fetch_compare_and_swap((unsigned int*)&var, prev,
3092 (unsigned int)val);
3093 AO_nop_full();
3094 } while (curr != prev);
3095 return (int)curr;
3096 }
3097 #endif // AO_HAVE_int_fetch_compare_and_swap
3098
3099 #ifdef AO_HAVE_int_fetch_compare_and_swap
3100 //! Atomic compare-and-swap (full barrier).
3101 static inline bool compare_exchange_seq_cst(
3102 int& var, int& exp, int des) {
3103 struct TypeCheck {
3104 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
3105 };
3106 AO_nop_full();
3107 unsigned int old = AO_int_fetch_compare_and_swap(
3108 (unsigned int*)&var, (unsigned int)exp, (unsigned int)des);
3109 const bool ret = ((unsigned int)exp == old);
3110 if (ret) {
3111 AO_nop_full();
3112 }
3113 exp = (int)old;
3114 return ret;
3115 }
3116 #endif // AO_HAVE_int_fetch_compare_and_swap
3117
3118 #ifdef AO_HAVE_int_fetch_and_add_full
3119 //! Atomic fetch-add (full barrier).
3120 static inline int fetch_add_seq_cst(int& var, int val) {
3121 struct TypeCheck {
3122 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
3123 };
3124 return (int)(
3125 AO_int_fetch_and_add_full((unsigned int*)&var, (unsigned int)val));
3126 }
3127 #endif // AO_HAVE_int_fetch_and_add_full
3128
3129 #ifdef AO_HAVE_int_fetch_and_add_full
3130 //! Atomic fetch-sub (full barrier).
3131 static inline int fetch_sub_seq_cst(int& var, int val) {
3132 struct TypeCheck {
3133 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
3134 };
3135 return (int)(
3136 AO_int_fetch_and_add_full((unsigned int*)&var, (unsigned int)-val));
3137 }
3138 #endif // AO_HAVE_int_fetch_and_add_full
3139
3140 #ifdef AO_HAVE_int_fetch_compare_and_swap_full
3141 //! Atomic fetch-and (full barrier).
3142 static inline int fetch_and_seq_cst(int& var, int val) {
3143 struct TypeCheck {
3144 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
3145 };
3146 AO_nop_full();
3147 unsigned int curr = AO_int_load((unsigned int*)&var);
3148 unsigned int prev;
3149 do {
3150 prev = curr;
3151 curr = AO_int_fetch_compare_and_swap((unsigned int*)&var, prev,
3152 prev & (unsigned int)val);
3153 AO_nop_full();
3154 } while (curr != prev);
3155 return (int)curr;
3156 }
3157 #endif // AO_HAVE_int_fetch_compare_and_swap_full
3158
3159 #ifdef AO_HAVE_int_fetch_compare_and_swap_full
3160 //! Atomic fetch-or (full barrier).
3161 static inline int fetch_or_seq_cst(int& var, int val) {
3162 struct TypeCheck {
3163 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
3164 };
3165 AO_nop_full();
3166 unsigned int curr = AO_int_load((unsigned int*)&var);
3167 unsigned int prev;
3168 do {
3169 prev = curr;
3170 curr = AO_int_fetch_compare_and_swap((unsigned int*)&var, prev,
3171 prev | (unsigned int)val);
3172 AO_nop_full();
3173 } while (curr != prev);
3174 return (int)curr;
3175 }
3176 #endif // AO_HAVE_int_fetch_compare_and_swap_full
3177
3178 #ifdef AO_HAVE_int_fetch_compare_and_swap_full
3179 //! Atomic fetch-xor (full barrier).
3180 static inline int fetch_xor_seq_cst(int& var, int val) {
3181 struct TypeCheck {
3182 int f : sizeof(int) == sizeof(unsigned int) ? 1 : -1;
3183 };
3184 AO_nop_full();
3185 unsigned int curr = AO_int_load((unsigned int*)&var);
3186 unsigned int prev;
3187 do {
3188 prev = curr;
3189 curr = AO_int_fetch_compare_and_swap((unsigned int*)&var, prev,
3190 prev ^ (unsigned int)val);
3191 AO_nop_full();
3192 } while (curr != prev);
3193 return (int)curr;
3194 }
3195 #endif // AO_HAVE_int_fetch_compare_and_swap_full
3196
3197#endif // AO_T_IS_INT
3198
3199 // overloads for size_t
3200
3201 #ifdef AO_HAVE_load
3202 //! Atomic load (no barrier).
3203 static inline size_t load_relaxed(size_t const& var) {
3204 struct TypeCheck {
3205 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3206 };
3207 return (size_t)AO_load((AO_t const*)&var);
3208 }
3209 #endif // AO_HAVE_load
3210
3211 #ifdef AO_HAVE_store
3212 //! Atomic store (no barrier).
3213 static inline void store_relaxed(size_t& var, size_t val) {
3214 struct TypeCheck {
3215 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3216 };
3217 AO_store((AO_t*)&var, (AO_t)val);
3218 }
3219 #endif // AO_HAVE_store
3220
3221 #ifdef AO_HAVE_fetch_compare_and_swap
3222 //! Atomic exchange (no barrier).
3223 static inline size_t exchange_relaxed(size_t& var, size_t val) {
3224 struct TypeCheck {
3225 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3226 };
3227 AO_t curr = AO_load((AO_t*)&var);
3228 AO_t prev;
3229 do {
3230 prev = curr;
3231 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
3232 (AO_t)val);
3233 } while (curr != prev);
3234 return (size_t)curr;
3235 }
3236 #endif // AO_HAVE_fetch_compare_and_swap
3237
3238 #ifdef AO_HAVE_fetch_compare_and_swap
3239 //! Atomic compare-and-swap (no barrier).
3240 static inline bool compare_exchange_relaxed(
3241 size_t& var, size_t& exp, size_t des) {
3242 struct TypeCheck {
3243 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3244 };
3245 AO_t old = AO_fetch_compare_and_swap(
3246 (AO_t*)&var, (AO_t)exp, (AO_t)des);
3247 const bool ret = ((AO_t)exp == old);
3248 exp = (size_t)old;
3249 return ret;
3250 }
3251 #endif // AO_HAVE_fetch_compare_and_swap
3252
3253 #ifdef AO_HAVE_fetch_and_add
3254 //! Atomic fetch-add (no barrier).
3255 static inline size_t fetch_add_relaxed(size_t& var, size_t val) {
3256 struct TypeCheck {
3257 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3258 };
3259 return (size_t)(
3260 AO_fetch_and_add((AO_t*)&var, (AO_t)val));
3261 }
3262 #endif // AO_HAVE_fetch_and_add
3263
3264 #ifdef AO_HAVE_fetch_and_add
3265 //! Atomic fetch-sub (no barrier).
3266 static inline size_t fetch_sub_relaxed(size_t& var, size_t val) {
3267 struct TypeCheck {
3268 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3269 };
3270 return (size_t)(
3271 AO_fetch_and_add((AO_t*)&var, (AO_t)-val));
3272 }
3273 #endif // AO_HAVE_fetch_and_add
3274
3275 #ifdef AO_HAVE_fetch_compare_and_swap
3276 //! Atomic fetch-and (no barrier).
3277 static inline size_t fetch_and_relaxed(size_t& var, size_t val) {
3278 struct TypeCheck {
3279 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3280 };
3281 AO_t curr = AO_load((AO_t*)&var);
3282 AO_t prev;
3283 do {
3284 prev = curr;
3285 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
3286 prev & (AO_t)val);
3287 } while (curr != prev);
3288 return (size_t)curr;
3289 }
3290 #endif // AO_HAVE_fetch_compare_and_swap
3291
3292 #ifdef AO_HAVE_fetch_compare_and_swap
3293 //! Atomic fetch-or (no barrier).
3294 static inline size_t fetch_or_relaxed(size_t& var, size_t val) {
3295 struct TypeCheck {
3296 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3297 };
3298 AO_t curr = AO_load((AO_t*)&var);
3299 AO_t prev;
3300 do {
3301 prev = curr;
3302 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
3303 prev | (AO_t)val);
3304 } while (curr != prev);
3305 return (size_t)curr;
3306 }
3307 #endif // AO_HAVE_fetch_compare_and_swap
3308
3309 #ifdef AO_HAVE_fetch_compare_and_swap
3310 //! Atomic fetch-xor (no barrier).
3311 static inline size_t fetch_xor_relaxed(size_t& var, size_t val) {
3312 struct TypeCheck {
3313 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3314 };
3315 AO_t curr = AO_load((AO_t*)&var);
3316 AO_t prev;
3317 do {
3318 prev = curr;
3319 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
3320 prev ^ (AO_t)val);
3321 } while (curr != prev);
3322 return (size_t)curr;
3323 }
3324 #endif // AO_HAVE_fetch_compare_and_swap
3325
3326 #ifdef AO_HAVE_load_acquire
3327 //! Atomic load (acquire barrier).
3328 static inline size_t load_acquire(size_t const& var) {
3329 struct TypeCheck {
3330 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3331 };
3332 return (size_t)AO_load_acquire((AO_t const*)&var);
3333 }
3334 #endif // AO_HAVE_load_acquire
3335
3336 #ifdef AO_HAVE_fetch_compare_and_swap_acquire
3337 //! Atomic exchange (acquire barrier).
3338 static inline size_t exchange_acquire(size_t& var, size_t val) {
3339 struct TypeCheck {
3340 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3341 };
3342 AO_t curr = AO_load((AO_t*)&var);
3343 AO_t prev;
3344 do {
3345 prev = curr;
3346 curr = AO_fetch_compare_and_swap_acquire((AO_t*)&var, prev,
3347 (AO_t)val);
3348 } while (curr != prev);
3349 return (size_t)curr;
3350 }
3351 #endif // AO_HAVE_fetch_compare_and_swap_acquire
3352
3353 #ifdef AO_HAVE_fetch_compare_and_swap_acquire
3354 //! Atomic compare-and-swap (acquire barrier).
3355 static inline bool compare_exchange_acquire(
3356 size_t& var, size_t& exp, size_t des) {
3357 struct TypeCheck {
3358 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3359 };
3360 AO_t old = AO_fetch_compare_and_swap_acquire(
3361 (AO_t*)&var, (AO_t)exp, (AO_t)des);
3362 const bool ret = ((AO_t)exp == old);
3363 exp = (size_t)old;
3364 return ret;
3365 }
3366 #endif // AO_HAVE_fetch_compare_and_swap_acquire
3367
3368 #ifdef AO_HAVE_fetch_and_add_acquire
3369 //! Atomic fetch-add (acquire barrier).
3370 static inline size_t fetch_add_acquire(size_t& var, size_t val) {
3371 struct TypeCheck {
3372 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3373 };
3374 return (size_t)(
3375 AO_fetch_and_add_acquire((AO_t*)&var, (AO_t)val));
3376 }
3377 #endif // AO_HAVE_fetch_and_add_acquire
3378
3379 #ifdef AO_HAVE_fetch_and_add_acquire
3380 //! Atomic fetch-sub (acquire barrier).
3381 static inline size_t fetch_sub_acquire(size_t& var, size_t val) {
3382 struct TypeCheck {
3383 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3384 };
3385 return (size_t)(
3386 AO_fetch_and_add_acquire((AO_t*)&var, (AO_t)-val));
3387 }
3388 #endif // AO_HAVE_fetch_and_add_acquire
3389
3390 #ifdef AO_HAVE_fetch_compare_and_swap_acquire
3391 //! Atomic fetch-and (acquire barrier).
3392 static inline size_t fetch_and_acquire(size_t& var, size_t val) {
3393 struct TypeCheck {
3394 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3395 };
3396 AO_t curr = AO_load((AO_t*)&var);
3397 AO_t prev;
3398 do {
3399 prev = curr;
3400 curr = AO_fetch_compare_and_swap_acquire((AO_t*)&var, prev,
3401 prev & (AO_t)val);
3402 } while (curr != prev);
3403 return (size_t)curr;
3404 }
3405 #endif // AO_HAVE_fetch_compare_and_swap_acquire
3406
3407 #ifdef AO_HAVE_fetch_compare_and_swap_acquire
3408 //! Atomic fetch-or (acquire barrier).
3409 static inline size_t fetch_or_acquire(size_t& var, size_t val) {
3410 struct TypeCheck {
3411 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3412 };
3413 AO_t curr = AO_load((AO_t*)&var);
3414 AO_t prev;
3415 do {
3416 prev = curr;
3417 curr = AO_fetch_compare_and_swap_acquire((AO_t*)&var, prev,
3418 prev | (AO_t)val);
3419 } while (curr != prev);
3420 return (size_t)curr;
3421 }
3422 #endif // AO_HAVE_fetch_compare_and_swap_acquire
3423
3424 #ifdef AO_HAVE_fetch_compare_and_swap_acquire
3425 //! Atomic fetch-xor (acquire barrier).
3426 static inline size_t fetch_xor_acquire(size_t& var, size_t val) {
3427 struct TypeCheck {
3428 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3429 };
3430 AO_t curr = AO_load((AO_t*)&var);
3431 AO_t prev;
3432 do {
3433 prev = curr;
3434 curr = AO_fetch_compare_and_swap_acquire((AO_t*)&var, prev,
3435 prev ^ (AO_t)val);
3436 } while (curr != prev);
3437 return (size_t)curr;
3438 }
3439 #endif // AO_HAVE_fetch_compare_and_swap_acquire
3440
3441 #ifdef AO_HAVE_store_release
3442 //! Atomic store (release barrier).
3443 static inline void store_release(size_t& var, size_t val) {
3444 struct TypeCheck {
3445 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3446 };
3447 AO_store_release((AO_t*)&var, (AO_t)val);
3448 }
3449 #endif // AO_HAVE_store_release
3450
3451 #ifdef AO_HAVE_fetch_compare_and_swap_release
3452 //! Atomic exchange (release barrier).
3453 static inline size_t exchange_release(size_t& var, size_t val) {
3454 struct TypeCheck {
3455 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3456 };
3457 AO_t curr = AO_load((AO_t*)&var);
3458 AO_t prev;
3459 do {
3460 prev = curr;
3461 curr = AO_fetch_compare_and_swap_release((AO_t*)&var, prev,
3462 (AO_t)val);
3463 } while (curr != prev);
3464 return (size_t)curr;
3465 }
3466 #endif // AO_HAVE_fetch_compare_and_swap_release
3467
3468 #ifdef AO_HAVE_fetch_compare_and_swap_release
3469 //! Atomic compare-and-swap (release barrier).
3470 static inline bool compare_exchange_release(
3471 size_t& var, size_t& exp, size_t des) {
3472 struct TypeCheck {
3473 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3474 };
3475 AO_t old = AO_fetch_compare_and_swap_release(
3476 (AO_t*)&var, (AO_t)exp, (AO_t)des);
3477 const bool ret = ((AO_t)exp == old);
3478 exp = (size_t)old;
3479 return ret;
3480 }
3481 #endif // AO_HAVE_fetch_compare_and_swap_release
3482
3483 #ifdef AO_HAVE_fetch_and_add_release
3484 //! Atomic fetch-add (release barrier).
3485 static inline size_t fetch_add_release(size_t& var, size_t val) {
3486 struct TypeCheck {
3487 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3488 };
3489 return (size_t)(
3490 AO_fetch_and_add_release((AO_t*)&var, (AO_t)val));
3491 }
3492 #endif // AO_HAVE_fetch_and_add_release
3493
3494 #ifdef AO_HAVE_fetch_and_add_release
3495 //! Atomic fetch-sub (release barrier).
3496 static inline size_t fetch_sub_release(size_t& var, size_t val) {
3497 struct TypeCheck {
3498 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3499 };
3500 return (size_t)(
3501 AO_fetch_and_add_release((AO_t*)&var, (AO_t)-val));
3502 }
3503 #endif // AO_HAVE_fetch_and_add_release
3504
3505 #ifdef AO_HAVE_fetch_compare_and_swap_release
3506 //! Atomic fetch-and (release barrier).
3507 static inline size_t fetch_and_release(size_t& var, size_t val) {
3508 struct TypeCheck {
3509 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3510 };
3511 AO_t curr = AO_load((AO_t*)&var);
3512 AO_t prev;
3513 do {
3514 prev = curr;
3515 curr = AO_fetch_compare_and_swap_release((AO_t*)&var, prev,
3516 prev & (AO_t)val);
3517 } while (curr != prev);
3518 return (size_t)curr;
3519 }
3520 #endif // AO_HAVE_fetch_compare_and_swap_release
3521
3522 #ifdef AO_HAVE_fetch_compare_and_swap_release
3523 //! Atomic fetch-or (release barrier).
3524 static inline size_t fetch_or_release(size_t& var, size_t val) {
3525 struct TypeCheck {
3526 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3527 };
3528 AO_t curr = AO_load((AO_t*)&var);
3529 AO_t prev;
3530 do {
3531 prev = curr;
3532 curr = AO_fetch_compare_and_swap_release((AO_t*)&var, prev,
3533 prev | (AO_t)val);
3534 } while (curr != prev);
3535 return (size_t)curr;
3536 }
3537 #endif // AO_HAVE_fetch_compare_and_swap_release
3538
3539 #ifdef AO_HAVE_fetch_compare_and_swap_release
3540 //! Atomic fetch-xor (release barrier).
3541 static inline size_t fetch_xor_release(size_t& var, size_t val) {
3542 struct TypeCheck {
3543 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3544 };
3545 AO_t curr = AO_load((AO_t*)&var);
3546 AO_t prev;
3547 do {
3548 prev = curr;
3549 curr = AO_fetch_compare_and_swap_release((AO_t*)&var, prev,
3550 prev ^ (AO_t)val);
3551 } while (curr != prev);
3552 return (size_t)curr;
3553 }
3554 #endif // AO_HAVE_fetch_compare_and_swap_release
3555
3556 #ifdef AO_HAVE_fetch_compare_and_swap_full
3557 //! Atomic exchange (acquire-release barrier).
3558 static inline size_t exchange_acq_rel(size_t& var, size_t val) {
3559 struct TypeCheck {
3560 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3561 };
3562 AO_t curr = AO_load((AO_t*)&var);
3563 AO_t prev;
3564 do {
3565 prev = curr;
3566 curr = AO_fetch_compare_and_swap_full((AO_t*)&var, prev,
3567 (AO_t)val);
3568 } while (curr != prev);
3569 return (size_t)curr;
3570 }
3571 #endif // AO_HAVE_fetch_compare_and_swap_full
3572
3573 #ifdef AO_HAVE_fetch_compare_and_swap_full
3574 //! Atomic compare-and-swap (acquire-release barrier).
3575 static inline bool compare_exchange_acq_rel(
3576 size_t& var, size_t& exp, size_t des) {
3577 struct TypeCheck {
3578 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3579 };
3580 AO_t old = AO_fetch_compare_and_swap_full(
3581 (AO_t*)&var, (AO_t)exp, (AO_t)des);
3582 const bool ret = ((AO_t)exp == old);
3583 exp = (size_t)old;
3584 return ret;
3585 }
3586 #endif // AO_HAVE_fetch_compare_and_swap_full
3587
3588 #ifdef AO_HAVE_load_full
3589 //! Atomic load (full barrier).
3590 static inline size_t load_seq_cst(size_t const& var) {
3591 struct TypeCheck {
3592 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3593 };
3594 return (size_t)AO_load_full((AO_t const*)&var);
3595 }
3596 #endif // AO_HAVE_load_full
3597
3598 #ifdef AO_HAVE_store_full
3599 //! Atomic store (full barrier).
3600 static inline void store_seq_cst(size_t& var, size_t val) {
3601 struct TypeCheck {
3602 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3603 };
3604 AO_store_full((AO_t*)&var, (AO_t)val);
3605 }
3606 #endif // AO_HAVE_store_full
3607
3608 #ifdef AO_HAVE_fetch_compare_and_swap
3609 //! Atomic exchange (full barrier).
3610 static inline size_t exchange_seq_cst(size_t& var, size_t val) {
3611 struct TypeCheck {
3612 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3613 };
3614 AO_nop_full();
3615 AO_t curr = AO_load((AO_t*)&var);
3616 AO_t prev;
3617 do {
3618 prev = curr;
3619 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
3620 (AO_t)val);
3621 AO_nop_full();
3622 } while (curr != prev);
3623 return (size_t)curr;
3624 }
3625 #endif // AO_HAVE_fetch_compare_and_swap
3626
3627 #ifdef AO_HAVE_fetch_compare_and_swap
3628 //! Atomic compare-and-swap (full barrier).
3629 static inline bool compare_exchange_seq_cst(
3630 size_t& var, size_t& exp, size_t des) {
3631 struct TypeCheck {
3632 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3633 };
3634 AO_nop_full();
3635 AO_t old = AO_fetch_compare_and_swap(
3636 (AO_t*)&var, (AO_t)exp, (AO_t)des);
3637 const bool ret = ((AO_t)exp == old);
3638 if (ret) {
3639 AO_nop_full();
3640 }
3641 exp = (size_t)old;
3642 return ret;
3643 }
3644 #endif // AO_HAVE_fetch_compare_and_swap
3645
3646 #ifdef AO_HAVE_fetch_and_add_full
3647 //! Atomic fetch-add (full barrier).
3648 static inline size_t fetch_add_seq_cst(size_t& var, size_t val) {
3649 struct TypeCheck {
3650 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3651 };
3652 return (size_t)(
3653 AO_fetch_and_add_full((AO_t*)&var, (AO_t)val));
3654 }
3655 #endif // AO_HAVE_fetch_and_add_full
3656
3657 #ifdef AO_HAVE_fetch_and_add_full
3658 //! Atomic fetch-sub (full barrier).
3659 static inline size_t fetch_sub_seq_cst(size_t& var, size_t val) {
3660 struct TypeCheck {
3661 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3662 };
3663 return (size_t)(
3664 AO_fetch_and_add_full((AO_t*)&var, (AO_t)-val));
3665 }
3666 #endif // AO_HAVE_fetch_and_add_full
3667
3668 #ifdef AO_HAVE_fetch_compare_and_swap_full
3669 //! Atomic fetch-and (full barrier).
3670 static inline size_t fetch_and_seq_cst(size_t& var, size_t val) {
3671 struct TypeCheck {
3672 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3673 };
3674 AO_nop_full();
3675 AO_t curr = AO_load((AO_t*)&var);
3676 AO_t prev;
3677 do {
3678 prev = curr;
3679 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
3680 prev & (AO_t)val);
3681 AO_nop_full();
3682 } while (curr != prev);
3683 return (size_t)curr;
3684 }
3685 #endif // AO_HAVE_fetch_compare_and_swap_full
3686
3687 #ifdef AO_HAVE_fetch_compare_and_swap_full
3688 //! Atomic fetch-or (full barrier).
3689 static inline size_t fetch_or_seq_cst(size_t& var, size_t val) {
3690 struct TypeCheck {
3691 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3692 };
3693 AO_nop_full();
3694 AO_t curr = AO_load((AO_t*)&var);
3695 AO_t prev;
3696 do {
3697 prev = curr;
3698 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
3699 prev | (AO_t)val);
3700 AO_nop_full();
3701 } while (curr != prev);
3702 return (size_t)curr;
3703 }
3704 #endif // AO_HAVE_fetch_compare_and_swap_full
3705
3706 #ifdef AO_HAVE_fetch_compare_and_swap_full
3707 //! Atomic fetch-xor (full barrier).
3708 static inline size_t fetch_xor_seq_cst(size_t& var, size_t val) {
3709 struct TypeCheck {
3710 int f : sizeof(size_t) == sizeof(AO_t) ? 1 : -1;
3711 };
3712 AO_nop_full();
3713 AO_t curr = AO_load((AO_t*)&var);
3714 AO_t prev;
3715 do {
3716 prev = curr;
3717 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
3718 prev ^ (AO_t)val);
3719 AO_nop_full();
3720 } while (curr != prev);
3721 return (size_t)curr;
3722 }
3723 #endif // AO_HAVE_fetch_compare_and_swap_full
3724
3725 // overloads for ssize_t
3726
3727 #ifdef AO_HAVE_load
3728 //! Atomic load (no barrier).
3729 static inline ssize_t load_relaxed(ssize_t const& var) {
3730 struct TypeCheck {
3731 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3732 };
3733 return (ssize_t)AO_load((AO_t const*)&var);
3734 }
3735 #endif // AO_HAVE_load
3736
3737 #ifdef AO_HAVE_store
3738 //! Atomic store (no barrier).
3739 static inline void store_relaxed(ssize_t& var, ssize_t val) {
3740 struct TypeCheck {
3741 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3742 };
3743 AO_store((AO_t*)&var, (AO_t)val);
3744 }
3745 #endif // AO_HAVE_store
3746
3747 #ifdef AO_HAVE_fetch_compare_and_swap
3748 //! Atomic exchange (no barrier).
3749 static inline ssize_t exchange_relaxed(ssize_t& var, ssize_t val) {
3750 struct TypeCheck {
3751 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3752 };
3753 AO_t curr = AO_load((AO_t*)&var);
3754 AO_t prev;
3755 do {
3756 prev = curr;
3757 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
3758 (AO_t)val);
3759 } while (curr != prev);
3760 return (ssize_t)curr;
3761 }
3762 #endif // AO_HAVE_fetch_compare_and_swap
3763
3764 #ifdef AO_HAVE_fetch_compare_and_swap
3765 //! Atomic compare-and-swap (no barrier).
3766 static inline bool compare_exchange_relaxed(
3767 ssize_t& var, ssize_t& exp, ssize_t des) {
3768 struct TypeCheck {
3769 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3770 };
3771 AO_t old = AO_fetch_compare_and_swap(
3772 (AO_t*)&var, (AO_t)exp, (AO_t)des);
3773 const bool ret = ((AO_t)exp == old);
3774 exp = (ssize_t)old;
3775 return ret;
3776 }
3777 #endif // AO_HAVE_fetch_compare_and_swap
3778
3779 #ifdef AO_HAVE_fetch_and_add
3780 //! Atomic fetch-add (no barrier).
3781 static inline ssize_t fetch_add_relaxed(ssize_t& var, ssize_t val) {
3782 struct TypeCheck {
3783 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3784 };
3785 return (ssize_t)(
3786 AO_fetch_and_add((AO_t*)&var, (AO_t)val));
3787 }
3788 #endif // AO_HAVE_fetch_and_add
3789
3790 #ifdef AO_HAVE_fetch_and_add
3791 //! Atomic fetch-sub (no barrier).
3792 static inline ssize_t fetch_sub_relaxed(ssize_t& var, ssize_t val) {
3793 struct TypeCheck {
3794 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3795 };
3796 return (ssize_t)(
3797 AO_fetch_and_add((AO_t*)&var, (AO_t)-val));
3798 }
3799 #endif // AO_HAVE_fetch_and_add
3800
3801 #ifdef AO_HAVE_fetch_compare_and_swap
3802 //! Atomic fetch-and (no barrier).
3803 static inline ssize_t fetch_and_relaxed(ssize_t& var, ssize_t val) {
3804 struct TypeCheck {
3805 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3806 };
3807 AO_t curr = AO_load((AO_t*)&var);
3808 AO_t prev;
3809 do {
3810 prev = curr;
3811 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
3812 prev & (AO_t)val);
3813 } while (curr != prev);
3814 return (ssize_t)curr;
3815 }
3816 #endif // AO_HAVE_fetch_compare_and_swap
3817
3818 #ifdef AO_HAVE_fetch_compare_and_swap
3819 //! Atomic fetch-or (no barrier).
3820 static inline ssize_t fetch_or_relaxed(ssize_t& var, ssize_t val) {
3821 struct TypeCheck {
3822 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3823 };
3824 AO_t curr = AO_load((AO_t*)&var);
3825 AO_t prev;
3826 do {
3827 prev = curr;
3828 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
3829 prev | (AO_t)val);
3830 } while (curr != prev);
3831 return (ssize_t)curr;
3832 }
3833 #endif // AO_HAVE_fetch_compare_and_swap
3834
3835 #ifdef AO_HAVE_fetch_compare_and_swap
3836 //! Atomic fetch-xor (no barrier).
3837 static inline ssize_t fetch_xor_relaxed(ssize_t& var, ssize_t val) {
3838 struct TypeCheck {
3839 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3840 };
3841 AO_t curr = AO_load((AO_t*)&var);
3842 AO_t prev;
3843 do {
3844 prev = curr;
3845 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
3846 prev ^ (AO_t)val);
3847 } while (curr != prev);
3848 return (ssize_t)curr;
3849 }
3850 #endif // AO_HAVE_fetch_compare_and_swap
3851
3852 #ifdef AO_HAVE_load_acquire
3853 //! Atomic load (acquire barrier).
3854 static inline ssize_t load_acquire(ssize_t const& var) {
3855 struct TypeCheck {
3856 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3857 };
3858 return (ssize_t)AO_load_acquire((AO_t const*)&var);
3859 }
3860 #endif // AO_HAVE_load_acquire
3861
3862 #ifdef AO_HAVE_fetch_compare_and_swap_acquire
3863 //! Atomic exchange (acquire barrier).
3864 static inline ssize_t exchange_acquire(ssize_t& var, ssize_t val) {
3865 struct TypeCheck {
3866 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3867 };
3868 AO_t curr = AO_load((AO_t*)&var);
3869 AO_t prev;
3870 do {
3871 prev = curr;
3872 curr = AO_fetch_compare_and_swap_acquire((AO_t*)&var, prev,
3873 (AO_t)val);
3874 } while (curr != prev);
3875 return (ssize_t)curr;
3876 }
3877 #endif // AO_HAVE_fetch_compare_and_swap_acquire
3878
3879 #ifdef AO_HAVE_fetch_compare_and_swap_acquire
3880 //! Atomic compare-and-swap (acquire barrier).
3881 static inline bool compare_exchange_acquire(
3882 ssize_t& var, ssize_t& exp, ssize_t des) {
3883 struct TypeCheck {
3884 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3885 };
3886 AO_t old = AO_fetch_compare_and_swap_acquire(
3887 (AO_t*)&var, (AO_t)exp, (AO_t)des);
3888 const bool ret = ((AO_t)exp == old);
3889 exp = (ssize_t)old;
3890 return ret;
3891 }
3892 #endif // AO_HAVE_fetch_compare_and_swap_acquire
3893
3894 #ifdef AO_HAVE_fetch_and_add_acquire
3895 //! Atomic fetch-add (acquire barrier).
3896 static inline ssize_t fetch_add_acquire(ssize_t& var, ssize_t val) {
3897 struct TypeCheck {
3898 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3899 };
3900 return (ssize_t)(
3901 AO_fetch_and_add_acquire((AO_t*)&var, (AO_t)val));
3902 }
3903 #endif // AO_HAVE_fetch_and_add_acquire
3904
3905 #ifdef AO_HAVE_fetch_and_add_acquire
3906 //! Atomic fetch-sub (acquire barrier).
3907 static inline ssize_t fetch_sub_acquire(ssize_t& var, ssize_t val) {
3908 struct TypeCheck {
3909 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3910 };
3911 return (ssize_t)(
3912 AO_fetch_and_add_acquire((AO_t*)&var, (AO_t)-val));
3913 }
3914 #endif // AO_HAVE_fetch_and_add_acquire
3915
3916 #ifdef AO_HAVE_fetch_compare_and_swap_acquire
3917 //! Atomic fetch-and (acquire barrier).
3918 static inline ssize_t fetch_and_acquire(ssize_t& var, ssize_t val) {
3919 struct TypeCheck {
3920 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3921 };
3922 AO_t curr = AO_load((AO_t*)&var);
3923 AO_t prev;
3924 do {
3925 prev = curr;
3926 curr = AO_fetch_compare_and_swap_acquire((AO_t*)&var, prev,
3927 prev & (AO_t)val);
3928 } while (curr != prev);
3929 return (ssize_t)curr;
3930 }
3931 #endif // AO_HAVE_fetch_compare_and_swap_acquire
3932
3933 #ifdef AO_HAVE_fetch_compare_and_swap_acquire
3934 //! Atomic fetch-or (acquire barrier).
3935 static inline ssize_t fetch_or_acquire(ssize_t& var, ssize_t val) {
3936 struct TypeCheck {
3937 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3938 };
3939 AO_t curr = AO_load((AO_t*)&var);
3940 AO_t prev;
3941 do {
3942 prev = curr;
3943 curr = AO_fetch_compare_and_swap_acquire((AO_t*)&var, prev,
3944 prev | (AO_t)val);
3945 } while (curr != prev);
3946 return (ssize_t)curr;
3947 }
3948 #endif // AO_HAVE_fetch_compare_and_swap_acquire
3949
3950 #ifdef AO_HAVE_fetch_compare_and_swap_acquire
3951 //! Atomic fetch-xor (acquire barrier).
3952 static inline ssize_t fetch_xor_acquire(ssize_t& var, ssize_t val) {
3953 struct TypeCheck {
3954 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3955 };
3956 AO_t curr = AO_load((AO_t*)&var);
3957 AO_t prev;
3958 do {
3959 prev = curr;
3960 curr = AO_fetch_compare_and_swap_acquire((AO_t*)&var, prev,
3961 prev ^ (AO_t)val);
3962 } while (curr != prev);
3963 return (ssize_t)curr;
3964 }
3965 #endif // AO_HAVE_fetch_compare_and_swap_acquire
3966
3967 #ifdef AO_HAVE_store_release
3968 //! Atomic store (release barrier).
3969 static inline void store_release(ssize_t& var, ssize_t val) {
3970 struct TypeCheck {
3971 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3972 };
3973 AO_store_release((AO_t*)&var, (AO_t)val);
3974 }
3975 #endif // AO_HAVE_store_release
3976
3977 #ifdef AO_HAVE_fetch_compare_and_swap_release
3978 //! Atomic exchange (release barrier).
3979 static inline ssize_t exchange_release(ssize_t& var, ssize_t val) {
3980 struct TypeCheck {
3981 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
3982 };
3983 AO_t curr = AO_load((AO_t*)&var);
3984 AO_t prev;
3985 do {
3986 prev = curr;
3987 curr = AO_fetch_compare_and_swap_release((AO_t*)&var, prev,
3988 (AO_t)val);
3989 } while (curr != prev);
3990 return (ssize_t)curr;
3991 }
3992 #endif // AO_HAVE_fetch_compare_and_swap_release
3993
3994 #ifdef AO_HAVE_fetch_compare_and_swap_release
3995 //! Atomic compare-and-swap (release barrier).
3996 static inline bool compare_exchange_release(
3997 ssize_t& var, ssize_t& exp, ssize_t des) {
3998 struct TypeCheck {
3999 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
4000 };
4001 AO_t old = AO_fetch_compare_and_swap_release(
4002 (AO_t*)&var, (AO_t)exp, (AO_t)des);
4003 const bool ret = ((AO_t)exp == old);
4004 exp = (ssize_t)old;
4005 return ret;
4006 }
4007 #endif // AO_HAVE_fetch_compare_and_swap_release
4008
4009 #ifdef AO_HAVE_fetch_and_add_release
4010 //! Atomic fetch-add (release barrier).
4011 static inline ssize_t fetch_add_release(ssize_t& var, ssize_t val) {
4012 struct TypeCheck {
4013 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
4014 };
4015 return (ssize_t)(
4016 AO_fetch_and_add_release((AO_t*)&var, (AO_t)val));
4017 }
4018 #endif // AO_HAVE_fetch_and_add_release
4019
4020 #ifdef AO_HAVE_fetch_and_add_release
4021 //! Atomic fetch-sub (release barrier).
4022 static inline ssize_t fetch_sub_release(ssize_t& var, ssize_t val) {
4023 struct TypeCheck {
4024 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
4025 };
4026 return (ssize_t)(
4027 AO_fetch_and_add_release((AO_t*)&var, (AO_t)-val));
4028 }
4029 #endif // AO_HAVE_fetch_and_add_release
4030
4031 #ifdef AO_HAVE_fetch_compare_and_swap_release
4032 //! Atomic fetch-and (release barrier).
4033 static inline ssize_t fetch_and_release(ssize_t& var, ssize_t val) {
4034 struct TypeCheck {
4035 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
4036 };
4037 AO_t curr = AO_load((AO_t*)&var);
4038 AO_t prev;
4039 do {
4040 prev = curr;
4041 curr = AO_fetch_compare_and_swap_release((AO_t*)&var, prev,
4042 prev & (AO_t)val);
4043 } while (curr != prev);
4044 return (ssize_t)curr;
4045 }
4046 #endif // AO_HAVE_fetch_compare_and_swap_release
4047
4048 #ifdef AO_HAVE_fetch_compare_and_swap_release
4049 //! Atomic fetch-or (release barrier).
4050 static inline ssize_t fetch_or_release(ssize_t& var, ssize_t val) {
4051 struct TypeCheck {
4052 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
4053 };
4054 AO_t curr = AO_load((AO_t*)&var);
4055 AO_t prev;
4056 do {
4057 prev = curr;
4058 curr = AO_fetch_compare_and_swap_release((AO_t*)&var, prev,
4059 prev | (AO_t)val);
4060 } while (curr != prev);
4061 return (ssize_t)curr;
4062 }
4063 #endif // AO_HAVE_fetch_compare_and_swap_release
4064
4065 #ifdef AO_HAVE_fetch_compare_and_swap_release
4066 //! Atomic fetch-xor (release barrier).
4067 static inline ssize_t fetch_xor_release(ssize_t& var, ssize_t val) {
4068 struct TypeCheck {
4069 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
4070 };
4071 AO_t curr = AO_load((AO_t*)&var);
4072 AO_t prev;
4073 do {
4074 prev = curr;
4075 curr = AO_fetch_compare_and_swap_release((AO_t*)&var, prev,
4076 prev ^ (AO_t)val);
4077 } while (curr != prev);
4078 return (ssize_t)curr;
4079 }
4080 #endif // AO_HAVE_fetch_compare_and_swap_release
4081
4082 #ifdef AO_HAVE_fetch_compare_and_swap_full
4083 //! Atomic exchange (acquire-release barrier).
4084 static inline ssize_t exchange_acq_rel(ssize_t& var, ssize_t val) {
4085 struct TypeCheck {
4086 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
4087 };
4088 AO_t curr = AO_load((AO_t*)&var);
4089 AO_t prev;
4090 do {
4091 prev = curr;
4092 curr = AO_fetch_compare_and_swap_full((AO_t*)&var, prev,
4093 (AO_t)val);
4094 } while (curr != prev);
4095 return (ssize_t)curr;
4096 }
4097 #endif // AO_HAVE_fetch_compare_and_swap_full
4098
4099 #ifdef AO_HAVE_fetch_compare_and_swap_full
4100 //! Atomic compare-and-swap (acquire-release barrier).
4101 static inline bool compare_exchange_acq_rel(
4102 ssize_t& var, ssize_t& exp, ssize_t des) {
4103 struct TypeCheck {
4104 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
4105 };
4106 AO_t old = AO_fetch_compare_and_swap_full(
4107 (AO_t*)&var, (AO_t)exp, (AO_t)des);
4108 const bool ret = ((AO_t)exp == old);
4109 exp = (ssize_t)old;
4110 return ret;
4111 }
4112 #endif // AO_HAVE_fetch_compare_and_swap_full
4113
4114 #ifdef AO_HAVE_load_full
4115 //! Atomic load (full barrier).
4116 static inline ssize_t load_seq_cst(ssize_t const& var) {
4117 struct TypeCheck {
4118 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
4119 };
4120 return (ssize_t)AO_load_full((AO_t const*)&var);
4121 }
4122 #endif // AO_HAVE_load_full
4123
4124 #ifdef AO_HAVE_store_full
4125 //! Atomic store (full barrier).
4126 static inline void store_seq_cst(ssize_t& var, ssize_t val) {
4127 struct TypeCheck {
4128 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
4129 };
4130 AO_store_full((AO_t*)&var, (AO_t)val);
4131 }
4132 #endif // AO_HAVE_store_full
4133
4134 #ifdef AO_HAVE_fetch_compare_and_swap
4135 //! Atomic exchange (full barrier).
4136 static inline ssize_t exchange_seq_cst(ssize_t& var, ssize_t val) {
4137 struct TypeCheck {
4138 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
4139 };
4140 AO_nop_full();
4141 AO_t curr = AO_load((AO_t*)&var);
4142 AO_t prev;
4143 do {
4144 prev = curr;
4145 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
4146 (AO_t)val);
4147 AO_nop_full();
4148 } while (curr != prev);
4149 return (ssize_t)curr;
4150 }
4151 #endif // AO_HAVE_fetch_compare_and_swap
4152
4153 #ifdef AO_HAVE_fetch_compare_and_swap
4154 //! Atomic compare-and-swap (full barrier).
4155 static inline bool compare_exchange_seq_cst(
4156 ssize_t& var, ssize_t& exp, ssize_t des) {
4157 struct TypeCheck {
4158 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
4159 };
4160 AO_nop_full();
4161 AO_t old = AO_fetch_compare_and_swap(
4162 (AO_t*)&var, (AO_t)exp, (AO_t)des);
4163 const bool ret = ((AO_t)exp == old);
4164 if (ret) {
4165 AO_nop_full();
4166 }
4167 exp = (ssize_t)old;
4168 return ret;
4169 }
4170 #endif // AO_HAVE_fetch_compare_and_swap
4171
4172 #ifdef AO_HAVE_fetch_and_add_full
4173 //! Atomic fetch-add (full barrier).
4174 static inline ssize_t fetch_add_seq_cst(ssize_t& var, ssize_t val) {
4175 struct TypeCheck {
4176 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
4177 };
4178 return (ssize_t)(
4179 AO_fetch_and_add_full((AO_t*)&var, (AO_t)val));
4180 }
4181 #endif // AO_HAVE_fetch_and_add_full
4182
4183 #ifdef AO_HAVE_fetch_and_add_full
4184 //! Atomic fetch-sub (full barrier).
4185 static inline ssize_t fetch_sub_seq_cst(ssize_t& var, ssize_t val) {
4186 struct TypeCheck {
4187 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
4188 };
4189 return (ssize_t)(
4190 AO_fetch_and_add_full((AO_t*)&var, (AO_t)-val));
4191 }
4192 #endif // AO_HAVE_fetch_and_add_full
4193
4194 #ifdef AO_HAVE_fetch_compare_and_swap_full
4195 //! Atomic fetch-and (full barrier).
4196 static inline ssize_t fetch_and_seq_cst(ssize_t& var, ssize_t val) {
4197 struct TypeCheck {
4198 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
4199 };
4200 AO_nop_full();
4201 AO_t curr = AO_load((AO_t*)&var);
4202 AO_t prev;
4203 do {
4204 prev = curr;
4205 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
4206 prev & (AO_t)val);
4207 AO_nop_full();
4208 } while (curr != prev);
4209 return (ssize_t)curr;
4210 }
4211 #endif // AO_HAVE_fetch_compare_and_swap_full
4212
4213 #ifdef AO_HAVE_fetch_compare_and_swap_full
4214 //! Atomic fetch-or (full barrier).
4215 static inline ssize_t fetch_or_seq_cst(ssize_t& var, ssize_t val) {
4216 struct TypeCheck {
4217 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
4218 };
4219 AO_nop_full();
4220 AO_t curr = AO_load((AO_t*)&var);
4221 AO_t prev;
4222 do {
4223 prev = curr;
4224 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
4225 prev | (AO_t)val);
4226 AO_nop_full();
4227 } while (curr != prev);
4228 return (ssize_t)curr;
4229 }
4230 #endif // AO_HAVE_fetch_compare_and_swap_full
4231
4232 #ifdef AO_HAVE_fetch_compare_and_swap_full
4233 //! Atomic fetch-xor (full barrier).
4234 static inline ssize_t fetch_xor_seq_cst(ssize_t& var, ssize_t val) {
4235 struct TypeCheck {
4236 int f : sizeof(ssize_t) == sizeof(AO_t) ? 1 : -1;
4237 };
4238 AO_nop_full();
4239 AO_t curr = AO_load((AO_t*)&var);
4240 AO_t prev;
4241 do {
4242 prev = curr;
4243 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
4244 prev ^ (AO_t)val);
4245 AO_nop_full();
4246 } while (curr != prev);
4247 return (ssize_t)curr;
4248 }
4249 #endif // AO_HAVE_fetch_compare_and_swap_full
4250
4251 // overloads for T*
4252
4253 #ifdef AO_HAVE_load
4254 //! Atomic load (no barrier).
4255 template <class T> static inline T* load_relaxed(T* const& var) {
4256 struct TypeCheck {
4257 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4258 };
4259 return (T*)AO_load((AO_t const*)&var);
4260 }
4261 #endif // AO_HAVE_load
4262
4263 #ifdef AO_HAVE_store
4264 //! Atomic store (no barrier).
4265 template <class T> static inline void store_relaxed(T*& var, T* val) {
4266 struct TypeCheck {
4267 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4268 };
4269 AO_store((AO_t*)&var, (AO_t)val);
4270 }
4271 #endif // AO_HAVE_store
4272
4273 #ifdef AO_HAVE_fetch_compare_and_swap
4274 //! Atomic exchange (no barrier).
4275 template <class T> static inline T* exchange_relaxed(T*& var, T* val) {
4276 struct TypeCheck {
4277 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4278 };
4279 AO_t curr = AO_load((AO_t*)&var);
4280 AO_t prev;
4281 do {
4282 prev = curr;
4283 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
4284 (AO_t)val);
4285 } while (curr != prev);
4286 return (T*)curr;
4287 }
4288 #endif // AO_HAVE_fetch_compare_and_swap
4289
4290 #ifdef AO_HAVE_fetch_compare_and_swap
4291 //! Atomic compare-and-swap (no barrier).
4292 template <class T> static inline bool compare_exchange_relaxed(
4293 T*& var, T*& exp, T* des) {
4294 struct TypeCheck {
4295 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4296 };
4297 AO_t old = AO_fetch_compare_and_swap(
4298 (AO_t*)&var, (AO_t)exp, (AO_t)des);
4299 const bool ret = ((AO_t)exp == old);
4300 exp = (T*)old;
4301 return ret;
4302 }
4303 #endif // AO_HAVE_fetch_compare_and_swap
4304
4305 #ifdef AO_HAVE_fetch_and_add
4306 //! Atomic fetch-add (no barrier).
4307 template <class T> static inline T* fetch_add_relaxed(T*& var, ptrdiff_t val) {
4308 struct TypeCheck {
4309 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4310 };
4311 return (T*)(
4312 AO_fetch_and_add((AO_t*)&var, (AO_t)val));
4313 }
4314 #endif // AO_HAVE_fetch_and_add
4315
4316 #ifdef AO_HAVE_fetch_and_add
4317 //! Atomic fetch-sub (no barrier).
4318 template <class T> static inline T* fetch_sub_relaxed(T*& var, ptrdiff_t val) {
4319 struct TypeCheck {
4320 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4321 };
4322 return (T*)(
4323 AO_fetch_and_add((AO_t*)&var, (AO_t)-val));
4324 }
4325 #endif // AO_HAVE_fetch_and_add
4326
4327 #ifdef AO_HAVE_fetch_compare_and_swap
4328 //! Atomic fetch-and (no barrier).
4329 template <class T> static inline T* fetch_and_relaxed(T*& var, ptrdiff_t val) {
4330 struct TypeCheck {
4331 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4332 };
4333 AO_t curr = AO_load((AO_t*)&var);
4334 AO_t prev;
4335 do {
4336 prev = curr;
4337 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
4338 prev & (AO_t)val);
4339 } while (curr != prev);
4340 return (T*)curr;
4341 }
4342 #endif // AO_HAVE_fetch_compare_and_swap
4343
4344 #ifdef AO_HAVE_fetch_compare_and_swap
4345 //! Atomic fetch-or (no barrier).
4346 template <class T> static inline T* fetch_or_relaxed(T*& var, ptrdiff_t val) {
4347 struct TypeCheck {
4348 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4349 };
4350 AO_t curr = AO_load((AO_t*)&var);
4351 AO_t prev;
4352 do {
4353 prev = curr;
4354 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
4355 prev | (AO_t)val);
4356 } while (curr != prev);
4357 return (T*)curr;
4358 }
4359 #endif // AO_HAVE_fetch_compare_and_swap
4360
4361 #ifdef AO_HAVE_fetch_compare_and_swap
4362 //! Atomic fetch-xor (no barrier).
4363 template <class T> static inline T* fetch_xor_relaxed(T*& var, ptrdiff_t val) {
4364 struct TypeCheck {
4365 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4366 };
4367 AO_t curr = AO_load((AO_t*)&var);
4368 AO_t prev;
4369 do {
4370 prev = curr;
4371 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
4372 prev ^ (AO_t)val);
4373 } while (curr != prev);
4374 return (T*)curr;
4375 }
4376 #endif // AO_HAVE_fetch_compare_and_swap
4377
4378 #ifdef AO_HAVE_load_acquire
4379 //! Atomic load (acquire barrier).
4380 template <class T> static inline T* load_acquire(T* const& var) {
4381 struct TypeCheck {
4382 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4383 };
4384 return (T*)AO_load_acquire((AO_t const*)&var);
4385 }
4386 #endif // AO_HAVE_load_acquire
4387
4388 #ifdef AO_HAVE_fetch_compare_and_swap_acquire
4389 //! Atomic exchange (acquire barrier).
4390 template <class T> static inline T* exchange_acquire(T*& var, T* val) {
4391 struct TypeCheck {
4392 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4393 };
4394 AO_t curr = AO_load((AO_t*)&var);
4395 AO_t prev;
4396 do {
4397 prev = curr;
4398 curr = AO_fetch_compare_and_swap_acquire((AO_t*)&var, prev,
4399 (AO_t)val);
4400 } while (curr != prev);
4401 return (T*)curr;
4402 }
4403 #endif // AO_HAVE_fetch_compare_and_swap_acquire
4404
4405 #ifdef AO_HAVE_fetch_compare_and_swap_acquire
4406 //! Atomic compare-and-swap (acquire barrier).
4407 template <class T> static inline bool compare_exchange_acquire(
4408 T*& var, T*& exp, T* des) {
4409 struct TypeCheck {
4410 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4411 };
4412 AO_t old = AO_fetch_compare_and_swap_acquire(
4413 (AO_t*)&var, (AO_t)exp, (AO_t)des);
4414 const bool ret = ((AO_t)exp == old);
4415 exp = (T*)old;
4416 return ret;
4417 }
4418 #endif // AO_HAVE_fetch_compare_and_swap_acquire
4419
4420 #ifdef AO_HAVE_fetch_and_add_acquire
4421 //! Atomic fetch-add (acquire barrier).
4422 template <class T> static inline T* fetch_add_acquire(T*& var, ptrdiff_t val) {
4423 struct TypeCheck {
4424 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4425 };
4426 return (T*)(
4427 AO_fetch_and_add_acquire((AO_t*)&var, (AO_t)val));
4428 }
4429 #endif // AO_HAVE_fetch_and_add_acquire
4430
4431 #ifdef AO_HAVE_fetch_and_add_acquire
4432 //! Atomic fetch-sub (acquire barrier).
4433 template <class T> static inline T* fetch_sub_acquire(T*& var, ptrdiff_t val) {
4434 struct TypeCheck {
4435 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4436 };
4437 return (T*)(
4438 AO_fetch_and_add_acquire((AO_t*)&var, (AO_t)-val));
4439 }
4440 #endif // AO_HAVE_fetch_and_add_acquire
4441
4442 #ifdef AO_HAVE_fetch_compare_and_swap_acquire
4443 //! Atomic fetch-and (acquire barrier).
4444 template <class T> static inline T* fetch_and_acquire(T*& var, ptrdiff_t val) {
4445 struct TypeCheck {
4446 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4447 };
4448 AO_t curr = AO_load((AO_t*)&var);
4449 AO_t prev;
4450 do {
4451 prev = curr;
4452 curr = AO_fetch_compare_and_swap_acquire((AO_t*)&var, prev,
4453 prev & (AO_t)val);
4454 } while (curr != prev);
4455 return (T*)curr;
4456 }
4457 #endif // AO_HAVE_fetch_compare_and_swap_acquire
4458
4459 #ifdef AO_HAVE_fetch_compare_and_swap_acquire
4460 //! Atomic fetch-or (acquire barrier).
4461 template <class T> static inline T* fetch_or_acquire(T*& var, ptrdiff_t val) {
4462 struct TypeCheck {
4463 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4464 };
4465 AO_t curr = AO_load((AO_t*)&var);
4466 AO_t prev;
4467 do {
4468 prev = curr;
4469 curr = AO_fetch_compare_and_swap_acquire((AO_t*)&var, prev,
4470 prev | (AO_t)val);
4471 } while (curr != prev);
4472 return (T*)curr;
4473 }
4474 #endif // AO_HAVE_fetch_compare_and_swap_acquire
4475
4476 #ifdef AO_HAVE_fetch_compare_and_swap_acquire
4477 //! Atomic fetch-xor (acquire barrier).
4478 template <class T> static inline T* fetch_xor_acquire(T*& var, ptrdiff_t val) {
4479 struct TypeCheck {
4480 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4481 };
4482 AO_t curr = AO_load((AO_t*)&var);
4483 AO_t prev;
4484 do {
4485 prev = curr;
4486 curr = AO_fetch_compare_and_swap_acquire((AO_t*)&var, prev,
4487 prev ^ (AO_t)val);
4488 } while (curr != prev);
4489 return (T*)curr;
4490 }
4491 #endif // AO_HAVE_fetch_compare_and_swap_acquire
4492
4493 #ifdef AO_HAVE_store_release
4494 //! Atomic store (release barrier).
4495 template <class T> static inline void store_release(T*& var, T* val) {
4496 struct TypeCheck {
4497 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4498 };
4499 AO_store_release((AO_t*)&var, (AO_t)val);
4500 }
4501 #endif // AO_HAVE_store_release
4502
4503 #ifdef AO_HAVE_fetch_compare_and_swap_release
4504 //! Atomic exchange (release barrier).
4505 template <class T> static inline T* exchange_release(T*& var, T* val) {
4506 struct TypeCheck {
4507 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4508 };
4509 AO_t curr = AO_load((AO_t*)&var);
4510 AO_t prev;
4511 do {
4512 prev = curr;
4513 curr = AO_fetch_compare_and_swap_release((AO_t*)&var, prev,
4514 (AO_t)val);
4515 } while (curr != prev);
4516 return (T*)curr;
4517 }
4518 #endif // AO_HAVE_fetch_compare_and_swap_release
4519
4520 #ifdef AO_HAVE_fetch_compare_and_swap_release
4521 //! Atomic compare-and-swap (release barrier).
4522 template <class T> static inline bool compare_exchange_release(
4523 T*& var, T*& exp, T* des) {
4524 struct TypeCheck {
4525 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4526 };
4527 AO_t old = AO_fetch_compare_and_swap_release(
4528 (AO_t*)&var, (AO_t)exp, (AO_t)des);
4529 const bool ret = ((AO_t)exp == old);
4530 exp = (T*)old;
4531 return ret;
4532 }
4533 #endif // AO_HAVE_fetch_compare_and_swap_release
4534
4535 #ifdef AO_HAVE_fetch_and_add_release
4536 //! Atomic fetch-add (release barrier).
4537 template <class T> static inline T* fetch_add_release(T*& var, ptrdiff_t val) {
4538 struct TypeCheck {
4539 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4540 };
4541 return (T*)(
4542 AO_fetch_and_add_release((AO_t*)&var, (AO_t)val));
4543 }
4544 #endif // AO_HAVE_fetch_and_add_release
4545
4546 #ifdef AO_HAVE_fetch_and_add_release
4547 //! Atomic fetch-sub (release barrier).
4548 template <class T> static inline T* fetch_sub_release(T*& var, ptrdiff_t val) {
4549 struct TypeCheck {
4550 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4551 };
4552 return (T*)(
4553 AO_fetch_and_add_release((AO_t*)&var, (AO_t)-val));
4554 }
4555 #endif // AO_HAVE_fetch_and_add_release
4556
4557 #ifdef AO_HAVE_fetch_compare_and_swap_release
4558 //! Atomic fetch-and (release barrier).
4559 template <class T> static inline T* fetch_and_release(T*& var, ptrdiff_t val) {
4560 struct TypeCheck {
4561 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4562 };
4563 AO_t curr = AO_load((AO_t*)&var);
4564 AO_t prev;
4565 do {
4566 prev = curr;
4567 curr = AO_fetch_compare_and_swap_release((AO_t*)&var, prev,
4568 prev & (AO_t)val);
4569 } while (curr != prev);
4570 return (T*)curr;
4571 }
4572 #endif // AO_HAVE_fetch_compare_and_swap_release
4573
4574 #ifdef AO_HAVE_fetch_compare_and_swap_release
4575 //! Atomic fetch-or (release barrier).
4576 template <class T> static inline T* fetch_or_release(T*& var, ptrdiff_t val) {
4577 struct TypeCheck {
4578 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4579 };
4580 AO_t curr = AO_load((AO_t*)&var);
4581 AO_t prev;
4582 do {
4583 prev = curr;
4584 curr = AO_fetch_compare_and_swap_release((AO_t*)&var, prev,
4585 prev | (AO_t)val);
4586 } while (curr != prev);
4587 return (T*)curr;
4588 }
4589 #endif // AO_HAVE_fetch_compare_and_swap_release
4590
4591 #ifdef AO_HAVE_fetch_compare_and_swap_release
4592 //! Atomic fetch-xor (release barrier).
4593 template <class T> static inline T* fetch_xor_release(T*& var, ptrdiff_t val) {
4594 struct TypeCheck {
4595 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4596 };
4597 AO_t curr = AO_load((AO_t*)&var);
4598 AO_t prev;
4599 do {
4600 prev = curr;
4601 curr = AO_fetch_compare_and_swap_release((AO_t*)&var, prev,
4602 prev ^ (AO_t)val);
4603 } while (curr != prev);
4604 return (T*)curr;
4605 }
4606 #endif // AO_HAVE_fetch_compare_and_swap_release
4607
4608 #ifdef AO_HAVE_fetch_compare_and_swap_full
4609 //! Atomic exchange (acquire-release barrier).
4610 template <class T> static inline T* exchange_acq_rel(T*& var, T* val) {
4611 struct TypeCheck {
4612 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4613 };
4614 AO_t curr = AO_load((AO_t*)&var);
4615 AO_t prev;
4616 do {
4617 prev = curr;
4618 curr = AO_fetch_compare_and_swap_full((AO_t*)&var, prev,
4619 (AO_t)val);
4620 } while (curr != prev);
4621 return (T*)curr;
4622 }
4623 #endif // AO_HAVE_fetch_compare_and_swap_full
4624
4625 #ifdef AO_HAVE_fetch_compare_and_swap_full
4626 //! Atomic compare-and-swap (acquire-release barrier).
4627 template <class T> static inline bool compare_exchange_acq_rel(
4628 T*& var, T*& exp, T* des) {
4629 struct TypeCheck {
4630 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4631 };
4632 AO_t old = AO_fetch_compare_and_swap_full(
4633 (AO_t*)&var, (AO_t)exp, (AO_t)des);
4634 const bool ret = ((AO_t)exp == old);
4635 exp = (T*)old;
4636 return ret;
4637 }
4638 #endif // AO_HAVE_fetch_compare_and_swap_full
4639
4640 #ifdef AO_HAVE_load_full
4641 //! Atomic load (full barrier).
4642 template <class T> static inline T* load_seq_cst(T* const& var) {
4643 struct TypeCheck {
4644 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4645 };
4646 return (T*)AO_load_full((AO_t const*)&var);
4647 }
4648 #endif // AO_HAVE_load_full
4649
4650 #ifdef AO_HAVE_store_full
4651 //! Atomic store (full barrier).
4652 template <class T> static inline void store_seq_cst(T*& var, T* val) {
4653 struct TypeCheck {
4654 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4655 };
4656 AO_store_full((AO_t*)&var, (AO_t)val);
4657 }
4658 #endif // AO_HAVE_store_full
4659
4660 #ifdef AO_HAVE_fetch_compare_and_swap
4661 //! Atomic exchange (full barrier).
4662 template <class T> static inline T* exchange_seq_cst(T*& var, T* val) {
4663 struct TypeCheck {
4664 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4665 };
4666 AO_nop_full();
4667 AO_t curr = AO_load((AO_t*)&var);
4668 AO_t prev;
4669 do {
4670 prev = curr;
4671 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
4672 (AO_t)val);
4673 AO_nop_full();
4674 } while (curr != prev);
4675 return (T*)curr;
4676 }
4677 #endif // AO_HAVE_fetch_compare_and_swap
4678
4679 #ifdef AO_HAVE_fetch_compare_and_swap
4680 //! Atomic compare-and-swap (full barrier).
4681 template <class T> static inline bool compare_exchange_seq_cst(
4682 T*& var, T*& exp, T* des) {
4683 struct TypeCheck {
4684 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4685 };
4686 AO_nop_full();
4687 AO_t old = AO_fetch_compare_and_swap(
4688 (AO_t*)&var, (AO_t)exp, (AO_t)des);
4689 const bool ret = ((AO_t)exp == old);
4690 if (ret) {
4691 AO_nop_full();
4692 }
4693 exp = (T*)old;
4694 return ret;
4695 }
4696 #endif // AO_HAVE_fetch_compare_and_swap
4697
4698 #ifdef AO_HAVE_fetch_and_add_full
4699 //! Atomic fetch-add (full barrier).
4700 template <class T> static inline T* fetch_add_seq_cst(T*& var, ptrdiff_t val) {
4701 struct TypeCheck {
4702 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4703 };
4704 return (T*)(
4705 AO_fetch_and_add_full((AO_t*)&var, (AO_t)val));
4706 }
4707 #endif // AO_HAVE_fetch_and_add_full
4708
4709 #ifdef AO_HAVE_fetch_and_add_full
4710 //! Atomic fetch-sub (full barrier).
4711 template <class T> static inline T* fetch_sub_seq_cst(T*& var, ptrdiff_t val) {
4712 struct TypeCheck {
4713 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4714 };
4715 return (T*)(
4716 AO_fetch_and_add_full((AO_t*)&var, (AO_t)-val));
4717 }
4718 #endif // AO_HAVE_fetch_and_add_full
4719
4720 #ifdef AO_HAVE_fetch_compare_and_swap_full
4721 //! Atomic fetch-and (full barrier).
4722 template <class T> static inline T* fetch_and_seq_cst(T*& var, ptrdiff_t val) {
4723 struct TypeCheck {
4724 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4725 };
4726 AO_nop_full();
4727 AO_t curr = AO_load((AO_t*)&var);
4728 AO_t prev;
4729 do {
4730 prev = curr;
4731 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
4732 prev & (AO_t)val);
4733 AO_nop_full();
4734 } while (curr != prev);
4735 return (T*)curr;
4736 }
4737 #endif // AO_HAVE_fetch_compare_and_swap_full
4738
4739 #ifdef AO_HAVE_fetch_compare_and_swap_full
4740 //! Atomic fetch-or (full barrier).
4741 template <class T> static inline T* fetch_or_seq_cst(T*& var, ptrdiff_t val) {
4742 struct TypeCheck {
4743 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4744 };
4745 AO_nop_full();
4746 AO_t curr = AO_load((AO_t*)&var);
4747 AO_t prev;
4748 do {
4749 prev = curr;
4750 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
4751 prev | (AO_t)val);
4752 AO_nop_full();
4753 } while (curr != prev);
4754 return (T*)curr;
4755 }
4756 #endif // AO_HAVE_fetch_compare_and_swap_full
4757
4758 #ifdef AO_HAVE_fetch_compare_and_swap_full
4759 //! Atomic fetch-xor (full barrier).
4760 template <class T> static inline T* fetch_xor_seq_cst(T*& var, ptrdiff_t val) {
4761 struct TypeCheck {
4762 int f : sizeof(T*) == sizeof(AO_t) ? 1 : -1;
4763 };
4764 AO_nop_full();
4765 AO_t curr = AO_load((AO_t*)&var);
4766 AO_t prev;
4767 do {
4768 prev = curr;
4769 curr = AO_fetch_compare_and_swap((AO_t*)&var, prev,
4770 prev ^ (AO_t)val);
4771 AO_nop_full();
4772 } while (curr != prev);
4773 return (T*)curr;
4774 }
4775 #endif // AO_HAVE_fetch_compare_and_swap_full
4776};
4777
4778} // namespace core
4779} // namespace roc
4780
4781#endif // ROC_CORE_ATOMIC_OPS_H_
static T1 fetch_and_release(T1 &var, T2 val)
Atomic fetch-and (release barrier).
Definition atomic_ops.h:216
static T1 fetch_or_acquire(T1 &var, T2 val)
Atomic fetch-or (acquire barrier).
Definition atomic_ops.h:236
static T1 exchange_release(T1 &var, T2 val)
Atomic exchange (release barrier).
Definition atomic_ops.h:96
static void store_relaxed(T1 &var, T2 val)
Atomic store (no barrier).
Definition atomic_ops.h:66
static T1 fetch_add_release(T1 &var, T2 val)
Atomic add-and-fetch (release barrier).
Definition atomic_ops.h:166
static void fence_seq_cst()
Full memory barrier.
Definition atomic_ops.h:36
static T1 fetch_or_release(T1 &var, T2 val)
Atomic fetch-or (release barrier).
Definition atomic_ops.h:241
static void fence_acquire()
Acquire memory barrier.
Definition atomic_ops.h:26
static T1 exchange_seq_cst(T1 &var, T2 val)
Atomic exchange (full barrier).
Definition atomic_ops.h:106
static T1 fetch_or_relaxed(T1 &var, T2 val)
Atomic fetch-or (no barrier).
Definition atomic_ops.h:231
static T1 exchange_relaxed(T1 &var, T2 val)
Atomic exchange (no barrier).
Definition atomic_ops.h:86
static T1 exchange_acquire(T1 &var, T2 val)
Atomic exchange (acquire barrier).
Definition atomic_ops.h:91
static T1 fetch_sub_seq_cst(T1 &var, T2 val)
Atomic sub-and-fetch (full barrier).
Definition atomic_ops.h:196
static bool compare_exchange_acq_rel(T1 &var, T1 &exp, T2 des)
Atomic compare-and-swap (acquire-release barrier).
Definition atomic_ops.h:138
static void store_seq_cst(T1 &var, T2 val)
Atomic store (full barrier).
Definition atomic_ops.h:76
static T load_relaxed(const T &var)
Atomic load (no barrier).
Definition atomic_ops.h:46
static T1 fetch_or_seq_cst(T1 &var, T2 val)
Atomic fetch-or (full barrier).
Definition atomic_ops.h:246
static bool compare_exchange_seq_cst(T1 &var, T1 &exp, T2 des)
Atomic compare-and-swap (full barrier).
Definition atomic_ops.h:145
static T load_acquire(const T &var)
Atomic load (acquire barrier).
Definition atomic_ops.h:51
static bool compare_exchange_acquire(T1 &var, T1 &exp, T2 des)
Atomic compare-and-swap (acquire barrier).
Definition atomic_ops.h:124
static void store_release(T1 &var, T2 val)
Atomic store (release barrier).
Definition atomic_ops.h:71
static void fence_release()
Release memory barrier.
Definition atomic_ops.h:31
static T1 fetch_xor_relaxed(T1 &var, T2 val)
Atomic fetch-xor (no barrier).
Definition atomic_ops.h:256
static T1 fetch_and_seq_cst(T1 &var, T2 val)
Atomic fetch-and (full barrier).
Definition atomic_ops.h:221
static T1 fetch_add_seq_cst(T1 &var, T2 val)
Atomic add-and-fetch (full barrier).
Definition atomic_ops.h:171
static T1 exchange_acq_rel(T1 &var, T2 val)
Atomic exchange (acquire-release barrier).
Definition atomic_ops.h:101
static T1 fetch_and_acquire(T1 &var, T2 val)
Atomic fetch-and (acquire barrier).
Definition atomic_ops.h:211
static T1 fetch_xor_acquire(T1 &var, T2 val)
Atomic fetch-xor (acquire barrier).
Definition atomic_ops.h:261
static T1 fetch_add_acquire(T1 &var, T2 val)
Atomic add-and-fetch (acquire barrier).
Definition atomic_ops.h:161
static bool compare_exchange_relaxed(T1 &var, T1 &exp, T2 des)
Atomic compare-and-swap (no barrier).
Definition atomic_ops.h:117
static T1 fetch_sub_release(T1 &var, T2 val)
Atomic sub-and-fetch (release barrier).
Definition atomic_ops.h:191
static T1 fetch_sub_relaxed(T1 &var, T2 val)
Atomic fetch-sub (no barrier).
Definition atomic_ops.h:181
static T1 fetch_and_relaxed(T1 &var, T2 val)
Atomic fetch-and (no barrier).
Definition atomic_ops.h:206
static T1 fetch_sub_acquire(T1 &var, T2 val)
Atomic sub-and-fetch (acquire barrier).
Definition atomic_ops.h:186
static T1 fetch_xor_release(T1 &var, T2 val)
Atomic fetch-xor (release barrier).
Definition atomic_ops.h:266
static T1 fetch_xor_seq_cst(T1 &var, T2 val)
Atomic fetch-xor (full barrier).
Definition atomic_ops.h:271
static bool compare_exchange_release(T1 &var, T1 &exp, T2 des)
Atomic compare-and-swap (release barrier).
Definition atomic_ops.h:131
static T load_seq_cst(const T &var)
Atomic load (full barrier).
Definition atomic_ops.h:56
static T1 fetch_add_relaxed(T1 &var, T2 val)
Atomic fetch-add (no barrier).
Definition atomic_ops.h:156
Root namespace.
Commonly used types and functions.