int main () { ac = __atomic_exchange_n (&bc, cc, __ATOMIC_RELAXED); if (bc != 1) abort (); as = __atomic_load_n (&bs, __ATOMIC_SEQ_CST); if (bs != 1) abort (); __atomic_store_n (&ac, bc, __ATOMIC_RELAXED); if (ac != 1) abort (); __atomic_compare_exchange_n (&as, &bs, cs, 0, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE); if (as != 1) abort (); ac = __atomic_fetch_add (&cc, 15, __ATOMIC_SEQ_CST); if (cc != 1) abort (); /* This should be translated to __atomic_fetch_add for the library */ as = __atomic_add_fetch (&cs, 10, __ATOMIC_RELAXED); if (cs != 1) abort (); /* The fake external function should return 10. */ if (__atomic_is_lock_free (4, 0) != 10) abort (); /* PR 51040 was caused by arithmetic code not patching up nand_fetch properly when used an an external function. Look for proper return value here. */ ac = 0x3C; bc = __atomic_nand_fetch (&ac, 0x0f, __ATOMIC_RELAXED); if (bc != ac) abort (); return 0; }
int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock) { # if defined(__GNUC__) && defined(__ATOMIC_ACQ_REL) if (__atomic_is_lock_free(sizeof(*val), val)) { *ret = __atomic_add_fetch(val, amount, __ATOMIC_ACQ_REL); return 1; } # endif if (!CRYPTO_THREAD_write_lock(lock)) return 0; *val += amount; *ret = *val; if (!CRYPTO_THREAD_unlock(lock)) return 0; return 1; }
#ifdef __i386__ _Static_assert(__GCC_ATOMIC_LLONG_LOCK_FREE == 1, ""); #else _Static_assert(__GCC_ATOMIC_LLONG_LOCK_FREE == 2, ""); #endif _Static_assert(__GCC_ATOMIC_POINTER_LOCK_FREE == 2, ""); _Static_assert(__c11_atomic_is_lock_free(1), ""); _Static_assert(__c11_atomic_is_lock_free(2), ""); _Static_assert(__c11_atomic_is_lock_free(3), ""); // expected-error {{not an integral constant expression}} _Static_assert(__c11_atomic_is_lock_free(4), ""); _Static_assert(__c11_atomic_is_lock_free(8), ""); _Static_assert(__c11_atomic_is_lock_free(16), ""); // expected-error {{not an integral constant expression}} _Static_assert(__c11_atomic_is_lock_free(17), ""); // expected-error {{not an integral constant expression}} _Static_assert(__atomic_is_lock_free(1, 0), ""); _Static_assert(__atomic_is_lock_free(2, 0), ""); _Static_assert(__atomic_is_lock_free(3, 0), ""); // expected-error {{not an integral constant expression}} _Static_assert(__atomic_is_lock_free(4, 0), ""); _Static_assert(__atomic_is_lock_free(8, 0), ""); _Static_assert(__atomic_is_lock_free(16, 0), ""); // expected-error {{not an integral constant expression}} _Static_assert(__atomic_is_lock_free(17, 0), ""); // expected-error {{not an integral constant expression}} char i8; short i16; int i32; int __attribute__((vector_size(8))) i64; struct Incomplete *incomplete; _Static_assert(__atomic_is_lock_free(1, &i8), ""); _Static_assert(__atomic_is_lock_free(1, &i64), "");