Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
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 
12 namespace roc {
13 namespace core {
14 
15 //! Atomic operations.
16 class AtomicOps {
17 public:
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.