static inline void atomic_daccum (double *p, const double val) { #if defined(ATOMIC_FP_FE_EMUL) double pv, upd; int done = 0; do { __atomic_load ((int64_t*)p, (int64_t*)&pv, __ATOMIC_ACQUIRE); if (__atomic_compare_exchange ((int64_t*)p, (int64_t*)&pv, (int64_t*)&NAN_EMPTY, 1, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) { upd = pv + val; __atomic_store ((int64_t*)p, (int64_t*)&upd, __ATOMIC_RELEASE); done = 1; } else MM_PAUSE(); } while (!done); #elif defined(ATOMIC_FP_OPTIMISTIC) double pv, upd; __atomic_load ((int64_t*)p, (int64_t*)&pv, __ATOMIC_ACQUIRE); do { upd = pv + val; if (__atomic_compare_exchange ((int64_t*)p, (int64_t*)&pv, (int64_t*)&upd, 1, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) break; else MM_PAUSE(); } while (1); #else OMP(omp atomic) *p += val; #endif }
/* Test for consistency on sizes 1, 2, 4, 8, 16 and 32. */ int main () { test_struct c; __atomic_store (&a, &zero, __ATOMIC_RELAXED); if (memcmp (&a, &zero, size)) abort (); __atomic_exchange (&a, &ones, &c, __ATOMIC_SEQ_CST); if (memcmp (&c, &zero, size)) abort (); if (memcmp (&a, &ones, size)) abort (); __atomic_load (&a, &b, __ATOMIC_RELAXED); if (memcmp (&b, &ones, size)) abort (); if (!__atomic_compare_exchange (&a, &b, &zero, false, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE)) abort(); if (memcmp (&a, &zero, size)) abort (); if (__atomic_compare_exchange (&a, &b, &ones, false, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE)) abort(); if (memcmp (&b, &zero, size)) abort (); return 0; }
void test_atomic_bool (_Atomic _Bool *a) { enum { SEQ_CST = __ATOMIC_SEQ_CST }; __atomic_fetch_add (a, 1, SEQ_CST); /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_fetch_add." } */ __atomic_fetch_sub (a, 1, SEQ_CST); /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_fetch_sub." } */ __atomic_fetch_and (a, 1, SEQ_CST); /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_fetch_and." } */ __atomic_fetch_xor (a, 1, SEQ_CST); /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_fetch_xor." } */ __atomic_fetch_or (a, 1, SEQ_CST); /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_fetch_or." } */ __atomic_fetch_nand (a, 1, SEQ_CST); /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_fetch_nand." } */ __atomic_add_fetch (a, 1, SEQ_CST); /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_add_fetch." } */ __atomic_sub_fetch (a, 1, SEQ_CST); /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_sub_fetch." } */ __atomic_and_fetch (a, 1, SEQ_CST); /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_and_fetch." } */ __atomic_xor_fetch (a, 1, SEQ_CST); /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_xor_fetch." } */ __atomic_or_fetch (a, 1, SEQ_CST); /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_or_fetch." } */ __atomic_nand_fetch (a, 1, SEQ_CST); /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_nand_fetch." } */ /* The following are valid and must be accepted. */ _Bool val = 0, ret = 0; __atomic_exchange (a, &val, &ret, SEQ_CST); __atomic_exchange_n (a, val, SEQ_CST); __atomic_compare_exchange (a, &val, &ret, !1, SEQ_CST, SEQ_CST); __atomic_compare_exchange_n (a, &val, ret, !1, SEQ_CST, SEQ_CST); __atomic_test_and_set (a, SEQ_CST); __atomic_clear (a, SEQ_CST); }
void lock(volatile int* thing) { int unlocked = UNLOCKED; int locked = LOCKED; while (!__atomic_compare_exchange(thing, &unlocked, &locked, true, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) { unlocked = UNLOCKED; } }
void unlock(volatile int* thing) { int unlocked = UNLOCKED; int locked = LOCKED; if (!__atomic_compare_exchange(thing, &locked, &unlocked, true, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) { locked = LOCKED; printf("Failed to release the lock\n"); } }
int main () { if (!__atomic_compare_exchange_n (&v, &expected, max, STRONG , __ATOMIC_RELAXED, __ATOMIC_RELAXED)) abort (); if (expected != 0) abort (); if (__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) abort (); if (expected != max) abort (); if (!__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) abort (); if (expected != max) abort (); if (v != 0) abort (); if (__atomic_compare_exchange_n (&v, &expected, desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) abort (); if (expected != 0) abort (); if (!__atomic_compare_exchange_n (&v, &expected, desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) abort (); if (expected != 0) abort (); if (v != max) abort (); /* Now test the generic version. */ v = 0; if (!__atomic_compare_exchange (&v, &expected, &max, STRONG, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) abort (); if (expected != 0) abort (); if (__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) abort (); if (expected != max) abort (); if (!__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) abort (); if (expected != max) abort (); if (v != 0) abort (); if (__atomic_compare_exchange (&v, &expected, &desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) abort (); if (expected != 0) abort (); if (!__atomic_compare_exchange (&v, &expected, &desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) abort (); if (expected != 0) abort (); if (v != max) abort (); return 0; }
__atomic_fetch_and(i, 3, memory_order_seq_cst); // expected-error {{pointer to integer}} __atomic_fetch_or(I, 3, memory_order_seq_cst); __atomic_fetch_xor(P, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer}} __atomic_fetch_or(D, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer}} __atomic_fetch_and(s1, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer}} _Bool cmpexch_1 = __c11_atomic_compare_exchange_strong(i, 0, 1, memory_order_seq_cst, memory_order_seq_cst); _Bool cmpexch_2 = __c11_atomic_compare_exchange_strong(p, 0, (int*)1, memory_order_seq_cst, memory_order_seq_cst); _Bool cmpexch_3 = __c11_atomic_compare_exchange_strong(d, (int*)0, 1, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{incompatible pointer types}} _Bool cmpexch_4 = __atomic_compare_exchange_n(I, I, 5, 1, memory_order_seq_cst, memory_order_seq_cst); _Bool cmpexch_5 = __atomic_compare_exchange_n(I, P, 5, 0, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{; dereference with *}} _Bool cmpexch_6 = __atomic_compare_exchange_n(I, I, P, 0, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{passing 'int **' to parameter of type 'int'}} _Bool cmpexch_7 = __atomic_compare_exchange(I, I, 5, 1, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{passing 'int' to parameter of type 'int *'}} _Bool cmpexch_8 = __atomic_compare_exchange(I, P, I, 0, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{; dereference with *}} _Bool cmpexch_9 = __atomic_compare_exchange(I, I, I, 0, memory_order_seq_cst, memory_order_seq_cst); const volatile int flag_k = 0; volatile int flag = 0; (void)(int)__atomic_test_and_set(&flag_k, memory_order_seq_cst); // expected-warning {{passing 'const volatile int *' to parameter of type 'volatile void *'}} (void)(int)__atomic_test_and_set(&flag, memory_order_seq_cst); __atomic_clear(&flag_k, memory_order_seq_cst); // expected-warning {{passing 'const volatile int *' to parameter of type 'volatile void *'}} __atomic_clear(&flag, memory_order_seq_cst); (int)__atomic_clear(&flag, memory_order_seq_cst); // expected-error {{operand of type 'void'}} const _Atomic(int) const_atomic; __c11_atomic_init(&const_atomic, 0); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}} __c11_atomic_store(&const_atomic, 0, memory_order_release); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}} __c11_atomic_load(&const_atomic, memory_order_acquire); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}}
static boolean_t catomic_compare_and_exchange_bool_acq (long *mem, long newval, long oldval) { return __atomic_compare_exchange (mem, &oldval, &newval, 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE); }
bool compare_exchange_strong(T& expected, T desired) noexcept { return __atomic_compare_exchange(&mElement, &expected, &desired, false, std::memory_order_seq_cst, std::memory_order_seq_cst); }