~ubuntu-branches/ubuntu/quantal/uclibc/quantal

« back to all changes in this revision

Viewing changes to include/atomic.h

  • Committer: Bazaar Package Importer
  • Author(s): Hector Oron
  • Date: 2011-06-11 03:06:20 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110611030620-ywjfvyuqvrpsm282
Tags: 0.9.32-1
* New upstream release
* Add myself as maintainer
* Bump standards version 
* Add Vcs-Git, Vcs-Browser and Homepage fields
* Add watch file 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Internal macros for atomic operations for GNU C Library.
2
 
   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
 
2
   Copyright (C) 2002-2006, 2009 Free Software Foundation, Inc.
3
3
   This file is part of the GNU C Library.
4
4
   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
5
5
 
21
21
#ifndef _ATOMIC_H
22
22
#define _ATOMIC_H       1
23
23
 
 
24
/* This header defines three types of macros:
 
25
 
 
26
   - atomic arithmetic and logic operation on memory.  They all
 
27
     have the prefix "atomic_".
 
28
 
 
29
   - conditionally atomic operations of the same kinds.  These
 
30
     always behave identical but can be faster when atomicity
 
31
     is not really needed since only one thread has access to
 
32
     the memory location.  In that case the code is slower in
 
33
     the multi-thread case.  The interfaces have the prefix
 
34
     "catomic_".
 
35
 
 
36
   - support functions like barriers.  They also have the preifx
 
37
     "atomic_".
 
38
 
 
39
   Architectures must provide a few lowlevel macros (the compare
 
40
   and exchange definitions).  All others are optional.  They
 
41
   should only be provided if the architecture has specific
 
42
   support for the operation.
 
43
 
 
44
   As <atomic.h> macros are usually heavily nested and often use local
 
45
   variables to make sure side-effects are evaluated properly, use for
 
46
   macro local variables a per-macro unique prefix.  This file uses
 
47
   __atgN_ prefix where N is different in each macro.  */
 
48
 
24
49
#include <stdlib.h>
25
50
 
26
51
#include <bits/atomic.h>
30
55
   and following args.  */
31
56
#define __atomic_val_bysize(pre, post, mem, ...)                              \
32
57
  ({                                                                          \
33
 
    __typeof (*mem) __result;                                                 \
 
58
    __typeof (*mem) __atg1_result;                                            \
34
59
    if (sizeof (*mem) == 1)                                                   \
35
 
      __result = pre##_8_##post (mem, __VA_ARGS__);                           \
 
60
      __atg1_result = pre##_8_##post (mem, __VA_ARGS__);                      \
36
61
    else if (sizeof (*mem) == 2)                                              \
37
 
      __result = pre##_16_##post (mem, __VA_ARGS__);                          \
 
62
      __atg1_result = pre##_16_##post (mem, __VA_ARGS__);                     \
38
63
    else if (sizeof (*mem) == 4)                                              \
39
 
      __result = pre##_32_##post (mem, __VA_ARGS__);                          \
 
64
      __atg1_result = pre##_32_##post (mem, __VA_ARGS__);                     \
40
65
    else if (sizeof (*mem) == 8)                                              \
41
 
      __result = pre##_64_##post (mem, __VA_ARGS__);                          \
 
66
      __atg1_result = pre##_64_##post (mem, __VA_ARGS__);                     \
42
67
    else                                                                      \
43
68
      abort ();                                                               \
44
 
    __result;                                                                 \
 
69
    __atg1_result;                                                            \
45
70
  })
46
71
#define __atomic_bool_bysize(pre, post, mem, ...)                             \
47
72
  ({                                                                          \
48
 
    int __result;                                                             \
 
73
    int __atg2_result;                                                        \
49
74
    if (sizeof (*mem) == 1)                                                   \
50
 
      __result = pre##_8_##post (mem, __VA_ARGS__);                           \
 
75
      __atg2_result = pre##_8_##post (mem, __VA_ARGS__);                      \
51
76
    else if (sizeof (*mem) == 2)                                              \
52
 
      __result = pre##_16_##post (mem, __VA_ARGS__);                          \
 
77
      __atg2_result = pre##_16_##post (mem, __VA_ARGS__);                     \
53
78
    else if (sizeof (*mem) == 4)                                              \
54
 
      __result = pre##_32_##post (mem, __VA_ARGS__);                          \
 
79
      __atg2_result = pre##_32_##post (mem, __VA_ARGS__);                     \
55
80
    else if (sizeof (*mem) == 8)                                              \
56
 
      __result = pre##_64_##post (mem, __VA_ARGS__);                          \
 
81
      __atg2_result = pre##_64_##post (mem, __VA_ARGS__);                     \
57
82
    else                                                                      \
58
83
      abort ();                                                               \
59
 
    __result;                                                                 \
 
84
    __atg2_result;                                                            \
60
85
  })
61
86
 
62
87
 
70
95
#endif
71
96
 
72
97
 
 
98
#ifndef catomic_compare_and_exchange_val_acq
 
99
# ifdef __arch_c_compare_and_exchange_val_32_acq
 
100
#  define catomic_compare_and_exchange_val_acq(mem, newval, oldval) \
 
101
  __atomic_val_bysize (__arch_c_compare_and_exchange_val,acq,                 \
 
102
                       mem, newval, oldval)
 
103
# else
 
104
#  define catomic_compare_and_exchange_val_acq(mem, newval, oldval) \
 
105
  atomic_compare_and_exchange_val_acq (mem, newval, oldval)
 
106
# endif
 
107
#endif
 
108
 
 
109
 
 
110
#ifndef catomic_compare_and_exchange_val_rel
 
111
# ifndef atomic_compare_and_exchange_val_rel
 
112
#  define catomic_compare_and_exchange_val_rel(mem, newval, oldval)           \
 
113
  catomic_compare_and_exchange_val_acq (mem, newval, oldval)
 
114
# else
 
115
#  define catomic_compare_and_exchange_val_rel(mem, newval, oldval)           \
 
116
  atomic_compare_and_exchange_val_rel (mem, newval, oldval)
 
117
# endif
 
118
#endif
 
119
 
 
120
 
73
121
#ifndef atomic_compare_and_exchange_val_rel
74
122
# define atomic_compare_and_exchange_val_rel(mem, newval, oldval)             \
75
123
  atomic_compare_and_exchange_val_acq (mem, newval, oldval)
83
131
#  define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
84
132
  __atomic_bool_bysize (__arch_compare_and_exchange_bool,acq,                 \
85
133
                        mem, newval, oldval)
86
 
#  else
87
 
#   define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
88
 
  ({ /* Cannot use __oldval here, because macros later in this file might     \
89
 
        call this macro with __oldval argument.  */                           \
90
 
     __typeof (oldval) __old = (oldval);                                      \
91
 
     atomic_compare_and_exchange_val_acq (mem, newval, __old) != __old;       \
92
 
  })
 
134
# else
 
135
#  define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
 
136
  ({ /* Cannot use __oldval here, because macros later in this file might     \
 
137
        call this macro with __oldval argument.  */                           \
 
138
     __typeof (oldval) __atg3_old = (oldval);                                 \
 
139
     atomic_compare_and_exchange_val_acq (mem, newval, __atg3_old)            \
 
140
       != __atg3_old;                                                         \
 
141
  })
 
142
# endif
 
143
#endif
 
144
 
 
145
 
 
146
#ifndef catomic_compare_and_exchange_bool_acq
 
147
# ifdef __arch_c_compare_and_exchange_bool_32_acq
 
148
#  define catomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
 
149
  __atomic_bool_bysize (__arch_c_compare_and_exchange_bool,acq,               \
 
150
                        mem, newval, oldval)
 
151
# else
 
152
#  define catomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
 
153
  ({ /* Cannot use __oldval here, because macros later in this file might     \
 
154
        call this macro with __oldval argument.  */                           \
 
155
     __typeof (oldval) __atg4_old = (oldval);                                 \
 
156
     catomic_compare_and_exchange_val_acq (mem, newval, __atg4_old)           \
 
157
       != __atg4_old;                                                         \
 
158
  })
 
159
# endif
 
160
#endif
 
161
 
 
162
 
 
163
#ifndef catomic_compare_and_exchange_bool_rel
 
164
# ifndef atomic_compare_and_exchange_bool_rel
 
165
#  define catomic_compare_and_exchange_bool_rel(mem, newval, oldval)          \
 
166
  catomic_compare_and_exchange_bool_acq (mem, newval, oldval)
 
167
# else
 
168
#  define catomic_compare_and_exchange_bool_rel(mem, newval, oldval)          \
 
169
  atomic_compare_and_exchange_bool_rel (mem, newval, oldval)
93
170
# endif
94
171
#endif
95
172
 
103
180
/* Store NEWVALUE in *MEM and return the old value.  */
104
181
#ifndef atomic_exchange_acq
105
182
# define atomic_exchange_acq(mem, newvalue) \
106
 
  ({ __typeof (*(mem)) __oldval;                                              \
107
 
     __typeof (mem) __memp = (mem);                                           \
108
 
     __typeof (*(mem)) __value = (newvalue);                                  \
 
183
  ({ __typeof (*(mem)) __atg5_oldval;                                         \
 
184
     __typeof (mem) __atg5_memp = (mem);                                      \
 
185
     __typeof (*(mem)) __atg5_value = (newvalue);                             \
109
186
                                                                              \
110
187
     do                                                                       \
111
 
       __oldval = (*__memp);                                                  \
112
 
     while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp,   \
113
 
                                                                    __value,  \
114
 
                                                                    __oldval),\
115
 
                              0));                                            \
 
188
       __atg5_oldval = *__atg5_memp;                                          \
 
189
     while (__builtin_expect                                                  \
 
190
            (atomic_compare_and_exchange_bool_acq (__atg5_memp, __atg5_value, \
 
191
                                                   __atg5_oldval), 0));       \
116
192
                                                                              \
117
 
     __oldval; })
 
193
     __atg5_oldval; })
118
194
#endif
119
195
 
120
196
#ifndef atomic_exchange_rel
125
201
/* Add VALUE to *MEM and return the old value of *MEM.  */
126
202
#ifndef atomic_exchange_and_add
127
203
# define atomic_exchange_and_add(mem, value) \
128
 
  ({ __typeof (*(mem)) __oldval;                                              \
129
 
     __typeof (mem) __memp = (mem);                                           \
130
 
     __typeof (*(mem)) __value = (value);                                     \
131
 
                                                                              \
132
 
     do                                                                       \
133
 
       __oldval = (*__memp);                                                  \
134
 
     while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp,   \
135
 
                                                                    __oldval  \
136
 
                                                                    + __value,\
137
 
                                                                    __oldval),\
138
 
                              0));                                            \
139
 
                                                                              \
140
 
     __oldval; })
 
204
  ({ __typeof (*(mem)) __atg6_oldval;                                         \
 
205
     __typeof (mem) __atg6_memp = (mem);                                      \
 
206
     __typeof (*(mem)) __atg6_value = (value);                                \
 
207
                                                                              \
 
208
     do                                                                       \
 
209
       __atg6_oldval = *__atg6_memp;                                          \
 
210
     while (__builtin_expect                                                  \
 
211
            (atomic_compare_and_exchange_bool_acq (__atg6_memp,               \
 
212
                                                   __atg6_oldval              \
 
213
                                                   + __atg6_value,            \
 
214
                                                   __atg6_oldval), 0));       \
 
215
                                                                              \
 
216
     __atg6_oldval; })
 
217
#endif
 
218
 
 
219
 
 
220
#ifndef catomic_exchange_and_add
 
221
# define catomic_exchange_and_add(mem, value) \
 
222
  ({ __typeof (*(mem)) __atg7_oldv;                                           \
 
223
     __typeof (mem) __atg7_memp = (mem);                                      \
 
224
     __typeof (*(mem)) __atg7_value = (value);                                \
 
225
                                                                              \
 
226
     do                                                                       \
 
227
       __atg7_oldv = *__atg7_memp;                                            \
 
228
     while (__builtin_expect                                                  \
 
229
            (catomic_compare_and_exchange_bool_acq (__atg7_memp,              \
 
230
                                                    __atg7_oldv               \
 
231
                                                    + __atg7_value,           \
 
232
                                                    __atg7_oldv), 0));        \
 
233
                                                                              \
 
234
     __atg7_oldv; })
 
235
#endif
 
236
 
 
237
 
 
238
#ifndef atomic_max
 
239
# define atomic_max(mem, value) \
 
240
  do {                                                                        \
 
241
    __typeof (*(mem)) __atg8_oldval;                                          \
 
242
    __typeof (mem) __atg8_memp = (mem);                                       \
 
243
    __typeof (*(mem)) __atg8_value = (value);                                 \
 
244
    do {                                                                      \
 
245
      __atg8_oldval = *__atg8_memp;                                           \
 
246
      if (__atg8_oldval >= __atg8_value)                                      \
 
247
        break;                                                                \
 
248
    } while (__builtin_expect                                                 \
 
249
             (atomic_compare_and_exchange_bool_acq (__atg8_memp, __atg8_value,\
 
250
                                                    __atg8_oldval), 0));      \
 
251
  } while (0)
 
252
#endif
 
253
 
 
254
 
 
255
#ifndef catomic_max
 
256
# define catomic_max(mem, value) \
 
257
  do {                                                                        \
 
258
    __typeof (*(mem)) __atg9_oldv;                                            \
 
259
    __typeof (mem) __atg9_memp = (mem);                                       \
 
260
    __typeof (*(mem)) __atg9_value = (value);                                 \
 
261
    do {                                                                      \
 
262
      __atg9_oldv = *__atg9_memp;                                             \
 
263
      if (__atg9_oldv >= __atg9_value)                                        \
 
264
        break;                                                                \
 
265
    } while (__builtin_expect                                                 \
 
266
             (catomic_compare_and_exchange_bool_acq (__atg9_memp,             \
 
267
                                                     __atg9_value,            \
 
268
                                                     __atg9_oldv), 0));       \
 
269
  } while (0)
 
270
#endif
 
271
 
 
272
 
 
273
#ifndef atomic_min
 
274
# define atomic_min(mem, value) \
 
275
  do {                                                                        \
 
276
    __typeof (*(mem)) __atg10_oldval;                                         \
 
277
    __typeof (mem) __atg10_memp = (mem);                                      \
 
278
    __typeof (*(mem)) __atg10_value = (value);                                \
 
279
    do {                                                                      \
 
280
      __atg10_oldval = *__atg10_memp;                                         \
 
281
      if (__atg10_oldval <= __atg10_value)                                    \
 
282
        break;                                                                \
 
283
    } while (__builtin_expect                                                 \
 
284
             (atomic_compare_and_exchange_bool_acq (__atg10_memp,             \
 
285
                                                    __atg10_value,            \
 
286
                                                    __atg10_oldval), 0));     \
 
287
  } while (0)
141
288
#endif
142
289
 
143
290
 
146
293
#endif
147
294
 
148
295
 
 
296
#ifndef catomic_add
 
297
# define catomic_add(mem, value) \
 
298
  (void) catomic_exchange_and_add ((mem), (value))
 
299
#endif
 
300
 
 
301
 
149
302
#ifndef atomic_increment
150
303
# define atomic_increment(mem) atomic_add ((mem), 1)
151
304
#endif
152
305
 
153
306
 
 
307
#ifndef catomic_increment
 
308
# define catomic_increment(mem) catomic_add ((mem), 1)
 
309
#endif
 
310
 
 
311
 
154
312
#ifndef atomic_increment_val
155
313
# define atomic_increment_val(mem) (atomic_exchange_and_add ((mem), 1) + 1)
156
314
#endif
157
315
 
158
316
 
 
317
#ifndef catomic_increment_val
 
318
# define catomic_increment_val(mem) (catomic_exchange_and_add ((mem), 1) + 1)
 
319
#endif
 
320
 
 
321
 
159
322
/* Add one to *MEM and return true iff it's now zero.  */
160
323
#ifndef atomic_increment_and_test
161
324
# define atomic_increment_and_test(mem) \
168
331
#endif
169
332
 
170
333
 
 
334
#ifndef catomic_decrement
 
335
# define catomic_decrement(mem) catomic_add ((mem), -1)
 
336
#endif
 
337
 
 
338
 
171
339
#ifndef atomic_decrement_val
172
340
# define atomic_decrement_val(mem) (atomic_exchange_and_add ((mem), -1) - 1)
173
341
#endif
174
342
 
175
343
 
 
344
#ifndef catomic_decrement_val
 
345
# define catomic_decrement_val(mem) (catomic_exchange_and_add ((mem), -1) - 1)
 
346
#endif
 
347
 
 
348
 
176
349
/* Subtract 1 from *MEM and return true iff it's now zero.  */
177
350
#ifndef atomic_decrement_and_test
178
351
# define atomic_decrement_and_test(mem) \
183
356
/* Decrement *MEM if it is > 0, and return the old value.  */
184
357
#ifndef atomic_decrement_if_positive
185
358
# define atomic_decrement_if_positive(mem) \
186
 
  ({ __typeof (*(mem)) __oldval;                                              \
187
 
     __typeof (mem) __memp = (mem);                                           \
 
359
  ({ __typeof (*(mem)) __atg11_oldval;                                        \
 
360
     __typeof (mem) __atg11_memp = (mem);                                     \
188
361
                                                                              \
189
362
     do                                                                       \
190
363
       {                                                                      \
191
 
         __oldval = *__memp;                                                  \
192
 
         if (__builtin_expect (__oldval <= 0, 0))                             \
 
364
         __atg11_oldval = *__atg11_memp;                                      \
 
365
         if (__builtin_expect (__atg11_oldval <= 0, 0))                       \
193
366
           break;                                                             \
194
367
       }                                                                      \
195
 
     while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp,   \
196
 
                                                                    __oldval  \
197
 
                                                                    - 1,      \
198
 
                                                                    __oldval),\
199
 
                              0));\
200
 
     __oldval; })
 
368
     while (__builtin_expect                                                  \
 
369
            (atomic_compare_and_exchange_bool_acq (__atg11_memp,              \
 
370
                                                   __atg11_oldval - 1,        \
 
371
                                                   __atg11_oldval), 0));      \
 
372
     __atg11_oldval; })
201
373
#endif
202
374
 
203
375
 
204
376
#ifndef atomic_add_negative
205
377
# define atomic_add_negative(mem, value)                                      \
206
 
  ({ __typeof (value) __aan_value = (value);                                  \
207
 
     atomic_exchange_and_add (mem, __aan_value) < -__aan_value; })
 
378
  ({ __typeof (value) __atg12_value = (value);                                \
 
379
     atomic_exchange_and_add (mem, __atg12_value) < -__atg12_value; })
208
380
#endif
209
381
 
210
382
 
211
383
#ifndef atomic_add_zero
212
384
# define atomic_add_zero(mem, value)                                          \
213
 
  ({ __typeof (value) __aaz_value = (value);                                  \
214
 
     atomic_exchange_and_add (mem, __aaz_value) == -__aaz_value; })
 
385
  ({ __typeof (value) __atg13_value = (value);                                \
 
386
     atomic_exchange_and_add (mem, __atg13_value) == -__atg13_value; })
215
387
#endif
216
388
 
217
389
 
223
395
 
224
396
#ifndef atomic_bit_test_set
225
397
# define atomic_bit_test_set(mem, bit) \
226
 
  ({ __typeof (*(mem)) __oldval;                                              \
227
 
     __typeof (mem) __memp = (mem);                                           \
228
 
     __typeof (*(mem)) __mask = ((__typeof (*(mem))) 1 << (bit));             \
229
 
                                                                              \
230
 
     do                                                                       \
231
 
       __oldval = (*__memp);                                                  \
232
 
     while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp,   \
233
 
                                                                    __oldval  \
234
 
                                                                    | __mask, \
235
 
                                                                    __oldval),\
236
 
                              0));                                            \
237
 
                                                                              \
238
 
     __oldval & __mask; })
239
 
#endif
240
 
 
 
398
  ({ __typeof (*(mem)) __atg14_old;                                           \
 
399
     __typeof (mem) __atg14_memp = (mem);                                     \
 
400
     __typeof (*(mem)) __atg14_mask = ((__typeof (*(mem))) 1 << (bit));       \
 
401
                                                                              \
 
402
     do                                                                       \
 
403
       __atg14_old = (*__atg14_memp);                                         \
 
404
     while (__builtin_expect                                                  \
 
405
            (atomic_compare_and_exchange_bool_acq (__atg14_memp,              \
 
406
                                                   __atg14_old | __atg14_mask,\
 
407
                                                   __atg14_old), 0));         \
 
408
                                                                              \
 
409
     __atg14_old & __atg14_mask; })
 
410
#endif
 
411
 
 
412
/* Atomically *mem &= mask.  */
 
413
#ifndef atomic_and
 
414
# define atomic_and(mem, mask) \
 
415
  do {                                                                        \
 
416
    __typeof (*(mem)) __atg15_old;                                            \
 
417
    __typeof (mem) __atg15_memp = (mem);                                      \
 
418
    __typeof (*(mem)) __atg15_mask = (mask);                                  \
 
419
                                                                              \
 
420
    do                                                                        \
 
421
      __atg15_old = (*__atg15_memp);                                          \
 
422
    while (__builtin_expect                                                   \
 
423
           (atomic_compare_and_exchange_bool_acq (__atg15_memp,               \
 
424
                                                  __atg15_old & __atg15_mask, \
 
425
                                                  __atg15_old), 0));          \
 
426
  } while (0)
 
427
#endif
 
428
 
 
429
#ifndef catomic_and
 
430
# define catomic_and(mem, mask) \
 
431
  do {                                                                        \
 
432
    __typeof (*(mem)) __atg20_old;                                            \
 
433
    __typeof (mem) __atg20_memp = (mem);                                      \
 
434
    __typeof (*(mem)) __atg20_mask = (mask);                                  \
 
435
                                                                              \
 
436
    do                                                                        \
 
437
      __atg20_old = (*__atg20_memp);                                          \
 
438
    while (__builtin_expect                                                   \
 
439
           (catomic_compare_and_exchange_bool_acq (__atg20_memp,              \
 
440
                                                   __atg20_old & __atg20_mask,\
 
441
                                                   __atg20_old), 0));         \
 
442
  } while (0)
 
443
#endif
 
444
 
 
445
/* Atomically *mem &= mask and return the old value of *mem.  */
 
446
#ifndef atomic_and_val
 
447
# define atomic_and_val(mem, mask) \
 
448
  ({ __typeof (*(mem)) __atg16_old;                                           \
 
449
     __typeof (mem) __atg16_memp = (mem);                                     \
 
450
     __typeof (*(mem)) __atg16_mask = (mask);                                 \
 
451
                                                                              \
 
452
     do                                                                       \
 
453
       __atg16_old = (*__atg16_memp);                                         \
 
454
     while (__builtin_expect                                                  \
 
455
            (atomic_compare_and_exchange_bool_acq (__atg16_memp,              \
 
456
                                                   __atg16_old & __atg16_mask,\
 
457
                                                   __atg16_old), 0));         \
 
458
                                                                              \
 
459
     __atg16_old; })
 
460
#endif
 
461
 
 
462
/* Atomically *mem |= mask and return the old value of *mem.  */
 
463
#ifndef atomic_or
 
464
# define atomic_or(mem, mask) \
 
465
  do {                                                                        \
 
466
    __typeof (*(mem)) __atg17_old;                                            \
 
467
    __typeof (mem) __atg17_memp = (mem);                                      \
 
468
    __typeof (*(mem)) __atg17_mask = (mask);                                  \
 
469
                                                                              \
 
470
    do                                                                        \
 
471
      __atg17_old = (*__atg17_memp);                                          \
 
472
    while (__builtin_expect                                                   \
 
473
           (atomic_compare_and_exchange_bool_acq (__atg17_memp,               \
 
474
                                                  __atg17_old | __atg17_mask, \
 
475
                                                  __atg17_old), 0));          \
 
476
  } while (0)
 
477
#endif
 
478
 
 
479
#ifndef catomic_or
 
480
# define catomic_or(mem, mask) \
 
481
  do {                                                                        \
 
482
    __typeof (*(mem)) __atg18_old;                                            \
 
483
    __typeof (mem) __atg18_memp = (mem);                                      \
 
484
    __typeof (*(mem)) __atg18_mask = (mask);                                  \
 
485
                                                                              \
 
486
    do                                                                        \
 
487
      __atg18_old = (*__atg18_memp);                                          \
 
488
    while (__builtin_expect                                                   \
 
489
           (catomic_compare_and_exchange_bool_acq (__atg18_memp,              \
 
490
                                                   __atg18_old | __atg18_mask,\
 
491
                                                   __atg18_old), 0));         \
 
492
  } while (0)
 
493
#endif
 
494
 
 
495
/* Atomically *mem |= mask and return the old value of *mem.  */
 
496
#ifndef atomic_or_val
 
497
# define atomic_or_val(mem, mask) \
 
498
  ({ __typeof (*(mem)) __atg19_old;                                           \
 
499
     __typeof (mem) __atg19_memp = (mem);                                     \
 
500
     __typeof (*(mem)) __atg19_mask = (mask);                                 \
 
501
                                                                              \
 
502
     do                                                                       \
 
503
       __atg19_old = (*__atg19_memp);                                         \
 
504
     while (__builtin_expect                                                  \
 
505
            (atomic_compare_and_exchange_bool_acq (__atg19_memp,              \
 
506
                                                   __atg19_old | __atg19_mask,\
 
507
                                                   __atg19_old), 0));         \
 
508
                                                                              \
 
509
     __atg19_old; })
 
510
#endif
241
511
 
242
512
#ifndef atomic_full_barrier
243
513
# define atomic_full_barrier() __asm__ ("" ::: "memory")
254
524
#endif
255
525
 
256
526
 
 
527
#ifndef atomic_forced_read
 
528
# define atomic_forced_read(x) \
 
529
  ({ __typeof (x) __x; __asm__ ("" : "=r" (__x) : "0" (x)); __x; })
 
530
#endif
 
531
 
 
532
 
257
533
#ifndef atomic_delay
258
534
# define atomic_delay() do { /* nothing */ } while (0)
259
535
#endif