diff options
Diffstat (limited to 'include/atomic.h')
-rw-r--r-- | include/atomic.h | 286 |
1 files changed, 142 insertions, 144 deletions
diff --git a/include/atomic.h b/include/atomic.h index 340c6e6..ec1e989 100644 --- a/include/atomic.h +++ b/include/atomic.h @@ -39,7 +39,12 @@ Architectures must provide a few lowlevel macros (the compare and exchange definitions). All others are optional. They should only be provided if the architecture has specific - support for the operation. */ + support for the operation. + + As <atomic.h> macros are usually heavily nested and often use local + variables to make sure side-effects are evaluated properly, use for + macro local variables a per-macro unique prefix. This file uses + __atgN_ prefix where N is different in each macro. */ #include <stdlib.h> @@ -50,33 +55,33 @@ and following args. */ #define __atomic_val_bysize(pre, post, mem, ...) \ ({ \ - __typeof (*mem) __result; \ + __typeof (*mem) __atg1_result; \ if (sizeof (*mem) == 1) \ - __result = pre##_8_##post (mem, __VA_ARGS__); \ + __atg1_result = pre##_8_##post (mem, __VA_ARGS__); \ else if (sizeof (*mem) == 2) \ - __result = pre##_16_##post (mem, __VA_ARGS__); \ + __atg1_result = pre##_16_##post (mem, __VA_ARGS__); \ else if (sizeof (*mem) == 4) \ - __result = pre##_32_##post (mem, __VA_ARGS__); \ + __atg1_result = pre##_32_##post (mem, __VA_ARGS__); \ else if (sizeof (*mem) == 8) \ - __result = pre##_64_##post (mem, __VA_ARGS__); \ + __atg1_result = pre##_64_##post (mem, __VA_ARGS__); \ else \ abort (); \ - __result; \ + __atg1_result; \ }) #define __atomic_bool_bysize(pre, post, mem, ...) \ ({ \ - int __result; \ + int __atg2_result; \ if (sizeof (*mem) == 1) \ - __result = pre##_8_##post (mem, __VA_ARGS__); \ + __atg2_result = pre##_8_##post (mem, __VA_ARGS__); \ else if (sizeof (*mem) == 2) \ - __result = pre##_16_##post (mem, __VA_ARGS__); \ + __atg2_result = pre##_16_##post (mem, __VA_ARGS__); \ else if (sizeof (*mem) == 4) \ - __result = pre##_32_##post (mem, __VA_ARGS__); \ + __atg2_result = pre##_32_##post (mem, __VA_ARGS__); \ else if (sizeof (*mem) == 8) \ - __result = pre##_64_##post (mem, __VA_ARGS__); \ + __atg2_result = pre##_64_##post (mem, __VA_ARGS__); \ else \ abort (); \ - __result; \ + __atg2_result; \ }) @@ -124,8 +129,9 @@ # define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \ ({ /* Cannot use __oldval here, because macros later in this file might \ call this macro with __oldval argument. */ \ - __typeof (oldval) __old = (oldval); \ - atomic_compare_and_exchange_val_acq (mem, newval, __old) != __old; \ + __typeof (oldval) __atg3_old = (oldval); \ + atomic_compare_and_exchange_val_acq (mem, newval, __atg3_old) \ + != __atg3_old; \ }) # endif #endif @@ -140,8 +146,9 @@ # define catomic_compare_and_exchange_bool_acq(mem, newval, oldval) \ ({ /* Cannot use __oldval here, because macros later in this file might \ call this macro with __oldval argument. */ \ - __typeof (oldval) __old = (oldval); \ - catomic_compare_and_exchange_val_acq (mem, newval, __old) != __old; \ + __typeof (oldval) __atg4_old = (oldval); \ + catomic_compare_and_exchange_val_acq (mem, newval, __atg4_old) \ + != __atg4_old; \ }) # endif #endif @@ -162,18 +169,17 @@ /* Store NEWVALUE in *MEM and return the old value. */ #ifndef atomic_exchange_acq # define atomic_exchange_acq(mem, newvalue) \ - ({ __typeof (*(mem)) __oldval; \ - __typeof (mem) __memp = (mem); \ - __typeof (*(mem)) __value = (newvalue); \ + ({ __typeof (*(mem)) __atg5_oldval; \ + __typeof (mem) __atg5_memp = (mem); \ + __typeof (*(mem)) __atg5_value = (newvalue); \ \ do \ - __oldval = *__memp; \ - while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \ - __value, \ - __oldval),\ - 0)); \ + __atg5_oldval = *__atg5_memp; \ + while (__builtin_expect \ + (atomic_compare_and_exchange_bool_acq (__atg5_memp, __atg5_value, \ + __atg5_oldval), 0)); \ \ - __oldval; }) + __atg5_oldval; }) #endif #ifndef atomic_exchange_rel @@ -184,54 +190,53 @@ /* Add VALUE to *MEM and return the old value of *MEM. */ #ifndef atomic_exchange_and_add # define atomic_exchange_and_add(mem, value) \ - ({ __typeof (*(mem)) __oldval; \ - __typeof (mem) __memp = (mem); \ - __typeof (*(mem)) __value = (value); \ + ({ __typeof (*(mem)) __atg6_oldval; \ + __typeof (mem) __atg6_memp = (mem); \ + __typeof (*(mem)) __atg6_value = (value); \ \ do \ - __oldval = *__memp; \ - while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \ - __oldval \ - + __value,\ - __oldval),\ - 0)); \ + __atg6_oldval = *__atg6_memp; \ + while (__builtin_expect \ + (atomic_compare_and_exchange_bool_acq (__atg6_memp, \ + __atg6_oldval \ + + __atg6_value, \ + __atg6_oldval), 0)); \ \ - __oldval; }) + __atg6_oldval; }) #endif #ifndef catomic_exchange_and_add # define catomic_exchange_and_add(mem, value) \ - ({ __typeof (*(mem)) __oldv; \ - __typeof (mem) __memp = (mem); \ - __typeof (*(mem)) __value = (value); \ + ({ __typeof (*(mem)) __atg7_oldv; \ + __typeof (mem) __atg7_memp = (mem); \ + __typeof (*(mem)) __atg7_value = (value); \ \ do \ - __oldv = *__memp; \ - while (__builtin_expect (catomic_compare_and_exchange_bool_acq (__memp, \ - __oldv \ - + __value,\ - __oldv), \ - 0)); \ + __atg7_oldv = *__atg7_memp; \ + while (__builtin_expect \ + (catomic_compare_and_exchange_bool_acq (__atg7_memp, \ + __atg7_oldv \ + + __atg7_value, \ + __atg7_oldv), 0)); \ \ - __oldv; }) + __atg7_oldv; }) #endif #ifndef atomic_max # define atomic_max(mem, value) \ do { \ - __typeof (*(mem)) __oldval; \ - __typeof (mem) __memp = (mem); \ - __typeof (*(mem)) __value = (value); \ + __typeof (*(mem)) __atg8_oldval; \ + __typeof (mem) __atg8_memp = (mem); \ + __typeof (*(mem)) __atg8_value = (value); \ do { \ - __oldval = *__memp; \ - if (__oldval >= __value) \ + __atg8_oldval = *__atg8_memp; \ + if (__atg8_oldval >= __atg8_value) \ break; \ - } while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \ - __value, \ - __oldval),\ - 0)); \ + } while (__builtin_expect \ + (atomic_compare_and_exchange_bool_acq (__atg8_memp, __atg8_value,\ + __atg8_oldval), 0)); \ } while (0) #endif @@ -239,17 +244,17 @@ #ifndef catomic_max # define catomic_max(mem, value) \ do { \ - __typeof (*(mem)) __oldv; \ - __typeof (mem) __memp = (mem); \ - __typeof (*(mem)) __value = (value); \ + __typeof (*(mem)) __atg9_oldv; \ + __typeof (mem) __atg9_memp = (mem); \ + __typeof (*(mem)) __atg9_value = (value); \ do { \ - __oldv = *__memp; \ - if (__oldv >= __value) \ + __atg9_oldv = *__atg9_memp; \ + if (__atg9_oldv >= __atg9_value) \ break; \ - } while (__builtin_expect (catomic_compare_and_exchange_bool_acq (__memp, \ - __value,\ - __oldv),\ - 0)); \ + } while (__builtin_expect \ + (catomic_compare_and_exchange_bool_acq (__atg9_memp, \ + __atg9_value, \ + __atg9_oldv), 0)); \ } while (0) #endif @@ -257,17 +262,17 @@ #ifndef atomic_min # define atomic_min(mem, value) \ do { \ - __typeof (*(mem)) __oldval; \ - __typeof (mem) __memp = (mem); \ - __typeof (*(mem)) __value = (value); \ + __typeof (*(mem)) __atg10_oldval; \ + __typeof (mem) __atg10_memp = (mem); \ + __typeof (*(mem)) __atg10_value = (value); \ do { \ - __oldval = *__memp; \ - if (__oldval <= __value) \ + __atg10_oldval = *__atg10_memp; \ + if (__atg10_oldval <= __atg10_value) \ break; \ - } while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \ - __value, \ - __oldval),\ - 0)); \ + } while (__builtin_expect \ + (atomic_compare_and_exchange_bool_acq (__atg10_memp, \ + __atg10_value, \ + __atg10_oldval), 0)); \ } while (0) #endif @@ -340,35 +345,34 @@ /* Decrement *MEM if it is > 0, and return the old value. */ #ifndef atomic_decrement_if_positive # define atomic_decrement_if_positive(mem) \ - ({ __typeof (*(mem)) __oldval; \ - __typeof (mem) __memp = (mem); \ + ({ __typeof (*(mem)) __atg11_oldval; \ + __typeof (mem) __atg11_memp = (mem); \ \ do \ { \ - __oldval = *__memp; \ - if (__builtin_expect (__oldval <= 0, 0)) \ + __atg11_oldval = *__atg11_memp; \ + if (__builtin_expect (__atg11_oldval <= 0, 0)) \ break; \ } \ - while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \ - __oldval \ - - 1, \ - __oldval),\ - 0));\ - __oldval; }) + while (__builtin_expect \ + (atomic_compare_and_exchange_bool_acq (__atg11_memp, \ + __atg11_oldval - 1, \ + __atg11_oldval), 0)); \ + __atg11_oldval; }) #endif #ifndef atomic_add_negative # define atomic_add_negative(mem, value) \ - ({ __typeof (value) __aan_value = (value); \ - atomic_exchange_and_add (mem, __aan_value) < -__aan_value; }) + ({ __typeof (value) __atg12_value = (value); \ + atomic_exchange_and_add (mem, __atg12_value) < -__atg12_value; }) #endif #ifndef atomic_add_zero # define atomic_add_zero(mem, value) \ - ({ __typeof (value) __aaz_value = (value); \ - atomic_exchange_and_add (mem, __aaz_value) == -__aaz_value; }) + ({ __typeof (value) __atg13_value = (value); \ + atomic_exchange_and_add (mem, __atg13_value) == -__atg13_value; }) #endif @@ -380,108 +384,102 @@ #ifndef atomic_bit_test_set # define atomic_bit_test_set(mem, bit) \ - ({ __typeof (*(mem)) __oldval; \ - __typeof (mem) __memp = (mem); \ - __typeof (*(mem)) __mask = ((__typeof (*(mem))) 1 << (bit)); \ + ({ __typeof (*(mem)) __atg14_old; \ + __typeof (mem) __atg14_memp = (mem); \ + __typeof (*(mem)) __atg14_mask = ((__typeof (*(mem))) 1 << (bit)); \ \ do \ - __oldval = (*__memp); \ - while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \ - __oldval \ - | __mask, \ - __oldval),\ - 0)); \ + __atg14_old = (*__atg14_memp); \ + while (__builtin_expect \ + (atomic_compare_and_exchange_bool_acq (__atg14_memp, \ + __atg14_old | __atg14_mask,\ + __atg14_old), 0)); \ \ - __oldval & __mask; }) + __atg14_old & __atg14_mask; }) #endif /* Atomically *mem &= mask. */ #ifndef atomic_and # define atomic_and(mem, mask) \ do { \ - __typeof (*(mem)) __oldval; \ - __typeof (mem) __memp = (mem); \ - __typeof (*(mem)) __mask = (mask); \ + __typeof (*(mem)) __atg15_old; \ + __typeof (mem) __atg15_memp = (mem); \ + __typeof (*(mem)) __atg15_mask = (mask); \ \ do \ - __oldval = (*__memp); \ - while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \ - __oldval \ - & __mask, \ - __oldval), \ - 0)); \ + __atg15_old = (*__atg15_memp); \ + while (__builtin_expect \ + (atomic_compare_and_exchange_bool_acq (__atg15_memp, \ + __atg15_old & __atg15_mask, \ + __atg15_old), 0)); \ } while (0) #endif /* Atomically *mem &= mask and return the old value of *mem. */ #ifndef atomic_and_val # define atomic_and_val(mem, mask) \ - ({ __typeof (*(mem)) __oldval; \ - __typeof (mem) __memp = (mem); \ - __typeof (*(mem)) __mask = (mask); \ + ({ __typeof (*(mem)) __atg16_old; \ + __typeof (mem) __atg16_memp = (mem); \ + __typeof (*(mem)) __atg16_mask = (mask); \ \ do \ - __oldval = (*__memp); \ - while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \ - __oldval \ - & __mask, \ - __oldval),\ - 0)); \ + __atg16_old = (*__atg16_memp); \ + while (__builtin_expect \ + (atomic_compare_and_exchange_bool_acq (__atg16_memp, \ + __atg16_old & __atg16_mask,\ + __atg16_old), 0)); \ \ - __oldval; }) + __atg16_old; }) #endif /* Atomically *mem |= mask and return the old value of *mem. */ #ifndef atomic_or # define atomic_or(mem, mask) \ do { \ - __typeof (*(mem)) __oldval; \ - __typeof (mem) __memp = (mem); \ - __typeof (*(mem)) __mask = (mask); \ + __typeof (*(mem)) __atg17_old; \ + __typeof (mem) __atg17_memp = (mem); \ + __typeof (*(mem)) __atg17_mask = (mask); \ \ do \ - __oldval = (*__memp); \ - while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \ - __oldval \ - | __mask, \ - __oldval), \ - 0)); \ + __atg17_old = (*__atg17_memp); \ + while (__builtin_expect \ + (atomic_compare_and_exchange_bool_acq (__atg17_memp, \ + __atg17_old | __atg17_mask, \ + __atg17_old), 0)); \ } while (0) #endif #ifndef catomic_or # define catomic_or(mem, mask) \ do { \ - __typeof (*(mem)) __oldval; \ - __typeof (mem) __memp = (mem); \ - __typeof (*(mem)) __mask = (mask); \ + __typeof (*(mem)) __atg18_old; \ + __typeof (mem) __atg18_memp = (mem); \ + __typeof (*(mem)) __atg18_mask = (mask); \ \ do \ - __oldval = (*__memp); \ - while (__builtin_expect (catomic_compare_and_exchange_bool_acq (__memp, \ - __oldval \ - | __mask, \ - __oldval),\ - 0)); \ + __atg18_old = (*__atg18_memp); \ + while (__builtin_expect \ + (catomic_compare_and_exchange_bool_acq (__atg18_memp, \ + __atg18_old | __atg18_mask,\ + __atg18_old), 0)); \ } while (0) #endif /* Atomically *mem |= mask and return the old value of *mem. */ #ifndef atomic_or_val # define atomic_or_val(mem, mask) \ - ({ __typeof (*(mem)) __oldval; \ - __typeof (mem) __memp = (mem); \ - __typeof (*(mem)) __mask = (mask); \ + ({ __typeof (*(mem)) __atg19_old; \ + __typeof (mem) __atg19_memp = (mem); \ + __typeof (*(mem)) __atg19_mask = (mask); \ \ do \ - __oldval = (*__memp); \ - while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \ - __oldval \ - | __mask, \ - __oldval),\ - 0)); \ + __atg19_old = (*__atg19_memp); \ + while (__builtin_expect \ + (atomic_compare_and_exchange_bool_acq (__atg19_memp, \ + __atg19_old | __atg19_mask,\ + __atg19_old), 0)); \ \ - __oldval; }) + __atg19_old; }) #endif #ifndef atomic_full_barrier |