/* * G R E E N H I L L S S O F T W A R E * Copyright (C) 2015-2016 by Green Hills Software, Inc. * * This software is proprietary and is the property of Green Hills * Software, Inc. Software is furnished under a license agreement and * is not to be disclosed to others except by the written permission * of the President of Green Hills Software, Inc. * ------------------------------------------------------------------- */ /* * Implement atomic operations used by C++11 atomic headers. Some targets * have instructions allowing atomic operations, while others require locks. */ #ifndef __GHS_ATOMIC_IMPL_H #define __GHS_ATOMIC_IMPL_H #include #include #include #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #if defined(__DO_DEF) /* atomic_ghs.c uses this */ #define __INLINE extern #else #define __INLINE extern inline __attribute__((always_inline)) #endif #if !defined(__OUT_OF_LINE_ATOMICS) #if defined(_NOBARRIERS) #undef _GHS_ATOMIC_BARRIER #define __GHS_ATOMIC_FENCE(POS, LDST, MO, DAT) _GHS_ATOMIC_NOP() extern inline _GHS_ATOMIC_NOP(void) {} #elif !defined(_HAS_ATOMIC_INTRINSIC) #define __GHS_ATOMIC_FENCE(POS, LDST, MO, DAT) _GHS_ATOMIC_BARRIER() #endif /* _NOBARRIERS / _HAS_ATOMIC_INTRINSIC */ _STD_BEGIN extern _Uint1_t __ghs_atomic_load_8(_Uint1_t *ptr, int mo); extern void __ghs_atomic_store_8(_Uint1_t *ptr, _Uint1_t val, int mo); extern _Uint1_t __ghs_atomic_fetch_add_8(_Uint1_t *ptr, _Uint1_t val, int mo); extern _Uint1_t __ghs_atomic_fetch_sub_8(_Uint1_t *ptr, _Uint1_t val, int mo); extern _Uint1_t __ghs_atomic_fetch_and_8(_Uint1_t *ptr, _Uint1_t val, int mo); extern _Uint1_t __ghs_atomic_fetch_xor_8(_Uint1_t *ptr, _Uint1_t val, int mo); extern _Uint1_t __ghs_atomic_fetch_or_8(_Uint1_t *ptr, _Uint1_t val, int mo); extern _Uint1_t __ghs_atomic_exchange_8(_Uint1_t *ptr, _Uint1_t val, int mo); extern bool __ghs_atomic_compare_exchange_8(_Uint1_t *ptr, _Uint1_t *exp, _Uint1_t val, bool weak, int mo1, int mo2); #if (_ATOMIC_MINBYTES_LOCK_FREE == 4) extern bool __ghs_atomic_compare_exchange_32_8(_Uint4_t *ptr, _Uint1_t *exp, _Uint4_t val, bool weak, int mo1, int mo2); extern _Uint4_t __ghs_atomic_fetch_add_32_8(_Uint4_t *ptr, _Uint4_t val, int mo); extern _Uint4_t __ghs_atomic_fetch_sub_32_8(_Uint4_t *ptr, _Uint4_t val, int mo); extern _Uint4_t __ghs_atomic_fetch_and_32_8(_Uint4_t *ptr, _Uint4_t val, int mo); extern _Uint4_t __ghs_atomic_fetch_or_32_8(_Uint4_t *ptr, _Uint4_t val, int mo); extern _Uint4_t __ghs_atomic_fetch_xor_32_8(_Uint4_t *ptr, _Uint4_t val, int mo); #endif extern _Uint2_t __ghs_atomic_load_16(_Uint2_t *ptr, int mo); extern void __ghs_atomic_store_16(_Uint2_t *ptr, _Uint2_t val, int mo); extern _Uint2_t __ghs_atomic_fetch_add_16(_Uint2_t *ptr, _Uint2_t val, int mo); extern _Uint2_t __ghs_atomic_fetch_sub_16(_Uint2_t *ptr, _Uint2_t val, int mo); extern _Uint2_t __ghs_atomic_fetch_and_16(_Uint2_t *ptr, _Uint2_t val, int mo); extern _Uint2_t __ghs_atomic_fetch_xor_16(_Uint2_t *ptr, _Uint2_t val, int mo); extern _Uint2_t __ghs_atomic_fetch_or_16(_Uint2_t *ptr, _Uint2_t val, int mo); extern _Uint2_t __ghs_atomic_exchange_16(_Uint2_t *ptr, _Uint2_t val, int mo); extern bool __ghs_atomic_compare_exchange_16(_Uint2_t *ptr, _Uint2_t *exp, _Uint2_t val, bool weak, int mo1, int mo2); #if (_ATOMIC_MINBYTES_LOCK_FREE == 4) extern bool __ghs_atomic_compare_exchange_32_16(_Uint4_t *ptr, _Uint2_t *exp, _Uint4_t val, bool weak, int mo1, int mo2); extern _Uint4_t __ghs_atomic_fetch_add_32_16(_Uint4_t *ptr, _Uint4_t val, int mo); extern _Uint4_t __ghs_atomic_fetch_sub_32_16(_Uint4_t *ptr, _Uint4_t val, int mo); extern _Uint4_t __ghs_atomic_fetch_and_32_16(_Uint4_t *ptr, _Uint4_t val, int mo); extern _Uint4_t __ghs_atomic_fetch_or_32_16(_Uint4_t *ptr, _Uint4_t val, int mo); extern _Uint4_t __ghs_atomic_fetch_xor_32_16(_Uint4_t *ptr, _Uint4_t val, int mo); #endif extern _Uint4_t __ghs_atomic_load_32(_Uint4_t *ptr, int mo); extern void __ghs_atomic_store_32(_Uint4_t *ptr, _Uint4_t val, int mo); extern _Uint4_t __ghs_atomic_fetch_add_32(_Uint4_t *ptr, _Uint4_t val, int mo); extern _Uint4_t __ghs_atomic_fetch_sub_32(_Uint4_t *ptr, _Uint4_t val, int mo); extern _Uint4_t __ghs_atomic_fetch_and_32(_Uint4_t *ptr, _Uint4_t val, int mo); extern _Uint4_t __ghs_atomic_fetch_xor_32(_Uint4_t *ptr, _Uint4_t val, int mo); extern _Uint4_t __ghs_atomic_fetch_or_32(_Uint4_t *ptr, _Uint4_t val, int mo); extern _Uint4_t __ghs_atomic_exchange_32(_Uint4_t *ptr, _Uint4_t val, int mo); extern bool __ghs_atomic_compare_exchange_32(_Uint4_t *ptr, _Uint4_t *exp, _Uint4_t val, bool weak, int mo1, int mo2); extern _Uint8_t __ghs_atomic_load_64(_Uint8_t *ptr, int mo); extern void __ghs_atomic_store_64(_Uint8_t *ptr, _Uint8_t val, int mo); extern _Uint8_t __ghs_atomic_fetch_add_64(_Uint8_t *ptr, _Uint8_t val, int mo); extern _Uint8_t __ghs_atomic_fetch_sub_64(_Uint8_t *ptr, _Uint8_t val, int mo); extern _Uint8_t __ghs_atomic_fetch_and_64(_Uint8_t *ptr, _Uint8_t val, int mo); extern _Uint8_t __ghs_atomic_fetch_xor_64(_Uint8_t *ptr, _Uint8_t val, int mo); extern _Uint8_t __ghs_atomic_fetch_or_64(_Uint8_t *ptr, _Uint8_t val, int mo); extern _Uint8_t __ghs_atomic_exchange_64(_Uint8_t *ptr, _Uint8_t val, int mo); extern bool __ghs_atomic_compare_exchange_64(_Uint8_t *ptr, _Uint8_t *exp, _Uint8_t val, bool weak, int mo1, int mo2); extern void __ghs_atomic_thread_fence(int mo); #if (_ATOMIC_MAXBYTES_LOCK_FREE >= 1) && (_ATOMIC_MINBYTES_LOCK_FREE <= 1) __INLINE void _Atomic_store_1(volatile _Uint1_t *_Tgt, _Uint1_t _Value, memory_order _Order) { __ghs_atomic_store_8((_Uint1_t *)_Tgt, _Value, _Order); } __INLINE _Uint1_t _Atomic_load_1(volatile _Uint1_t *_Tgt, memory_order _Order) { return __ghs_atomic_load_8((_Uint1_t *)_Tgt, _Order); } __INLINE _Uint1_t _Atomic_exchange_1(volatile _Uint1_t *_Tgt, _Uint1_t _Value, memory_order _Order) { return __ghs_atomic_exchange_8((_Uint1_t *)_Tgt, _Value, _Order); } __INLINE int _Atomic_compare_exchange_strong_1(volatile _Uint1_t *_Tgt, _Uint1_t *_Exp, _Uint1_t _Value, memory_order _Order1, memory_order _Order2) { return __ghs_atomic_compare_exchange_8((_Uint1_t *)_Tgt, _Exp, _Value, false, _Order1, _Order2); } __INLINE int _Atomic_compare_exchange_weak_1(volatile _Uint1_t *_Tgt, _Uint1_t *_Exp, _Uint1_t _Value, memory_order _Order1, memory_order _Order2) { return __ghs_atomic_compare_exchange_8((_Uint1_t *)_Tgt, _Exp, _Value, true, _Order1, _Order2); } __INLINE _Uint1_t _Atomic_fetch_add_1(volatile _Uint1_t *_Tgt, _Uint1_t _Value, memory_order _Order) { return __ghs_atomic_fetch_add_8((_Uint1_t *)_Tgt, _Value, _Order); } __INLINE _Uint1_t _Atomic_fetch_sub_1(volatile _Uint1_t *_Tgt, _Uint1_t _Value, memory_order _Order) { return __ghs_atomic_fetch_sub_8((_Uint1_t *)_Tgt, _Value, _Order); } __INLINE _Uint1_t _Atomic_fetch_and_1(volatile _Uint1_t *_Tgt, _Uint1_t _Value, memory_order _Order) { return __ghs_atomic_fetch_and_8((_Uint1_t *)_Tgt, _Value, _Order); } __INLINE _Uint1_t _Atomic_fetch_or_1(volatile _Uint1_t *_Tgt, _Uint1_t _Value, memory_order _Order) { return __ghs_atomic_fetch_or_8((_Uint1_t *)_Tgt, _Value, _Order); } __INLINE _Uint1_t _Atomic_fetch_xor_1(volatile _Uint1_t *_Tgt, _Uint1_t _Value, memory_order _Order) { return __ghs_atomic_fetch_xor_8((_Uint1_t *)_Tgt, _Value, _Order); } #endif /*(_ATOMIC_MAXBYTES_LOCK_FREE>=1) && (_ATOMIC_MINBYTES_LOCK_FREE<=1)*/ #if (_ATOMIC_MAXBYTES_LOCK_FREE >= 2) && (_ATOMIC_MINBYTES_LOCK_FREE <= 2) __INLINE void _Atomic_store_2(volatile _Uint2_t *_Tgt, _Uint2_t _Value, memory_order _Order) { __ghs_atomic_store_16((_Uint2_t *)_Tgt, _Value, _Order); } __INLINE _Uint2_t _Atomic_load_2(volatile _Uint2_t *_Tgt, memory_order _Order) { return __ghs_atomic_load_16((_Uint2_t *)_Tgt, _Order); } __INLINE _Uint2_t _Atomic_exchange_2(volatile _Uint2_t *_Tgt, _Uint2_t _Value, memory_order _Order) { return __ghs_atomic_exchange_16((_Uint2_t *)_Tgt, _Value, _Order); } __INLINE int _Atomic_compare_exchange_strong_2(volatile _Uint2_t *_Tgt, _Uint2_t *_Exp, _Uint2_t _Value, memory_order _Order1, memory_order _Order2) { return __ghs_atomic_compare_exchange_16((_Uint2_t *)_Tgt, _Exp, _Value, false, _Order1, _Order2); } __INLINE int _Atomic_compare_exchange_weak_2(volatile _Uint2_t *_Tgt, _Uint2_t *_Exp, _Uint2_t _Value, memory_order _Order1, memory_order _Order2) { return __ghs_atomic_compare_exchange_16((_Uint2_t *)_Tgt, _Exp, _Value, true, _Order1, _Order2); } __INLINE _Uint2_t _Atomic_fetch_add_2(volatile _Uint2_t *_Tgt, _Uint2_t _Value, memory_order _Order) { return __ghs_atomic_fetch_add_16((_Uint2_t *)_Tgt, _Value, _Order); } __INLINE _Uint2_t _Atomic_fetch_sub_2(volatile _Uint2_t *_Tgt, _Uint2_t _Value, memory_order _Order) { return __ghs_atomic_fetch_sub_16((_Uint2_t *)_Tgt, _Value, _Order); } __INLINE _Uint2_t _Atomic_fetch_and_2(volatile _Uint2_t *_Tgt, _Uint2_t _Value, memory_order _Order) { return __ghs_atomic_fetch_and_16((_Uint2_t *)_Tgt, _Value, _Order); } __INLINE _Uint2_t _Atomic_fetch_or_2(volatile _Uint2_t *_Tgt, _Uint2_t _Value, memory_order _Order) { return __ghs_atomic_fetch_or_16((_Uint2_t *)_Tgt, _Value, _Order); } __INLINE _Uint2_t _Atomic_fetch_xor_2(volatile _Uint2_t *_Tgt, _Uint2_t _Value, memory_order _Order) { return __ghs_atomic_fetch_xor_16((_Uint2_t *)_Tgt, _Value, _Order); } #endif /*(_ATOMIC_MAXBYTES_LOCK_FREE>=2) && (_ATOMIC_MINBYTES_LOCK_FREE<=2)*/ #if (_ATOMIC_MAXBYTES_LOCK_FREE >= 4) __INLINE void _Atomic_store_4(volatile _Uint4_t *_Tgt, _Uint4_t _Value, memory_order _Order) { __ghs_atomic_store_32((_Uint4_t *)_Tgt, _Value, _Order); } __INLINE _Uint4_t _Atomic_load_4(volatile _Uint4_t *_Tgt, memory_order _Order) { return __ghs_atomic_load_32((_Uint4_t *)_Tgt, _Order); } __INLINE _Uint4_t _Atomic_exchange_4(volatile _Uint4_t *_Tgt, _Uint4_t _Value, memory_order _Order) { return __ghs_atomic_exchange_32((_Uint4_t *)_Tgt, _Value, _Order); } __INLINE int _Atomic_compare_exchange_strong_4(volatile _Uint4_t *_Tgt, _Uint4_t *_Exp, _Uint4_t _Value, memory_order _Order1, memory_order _Order2) { return __ghs_atomic_compare_exchange_32((_Uint4_t *)_Tgt, _Exp, _Value, false, _Order1, _Order2); } #if (_ATOMIC_MINBYTES_LOCK_FREE == 4) __INLINE int _Atomic_compare_exchange_strong_4_1(volatile _Uint4_t *_Tgt, _Uint1_t *_Exp, _Uint1_t _Value, memory_order _Order1, memory_order _Order2) { return __ghs_atomic_compare_exchange_32_8((_Uint4_t *)_Tgt, _Exp, _Value, false, _Order1, _Order2); } __INLINE int _Atomic_compare_exchange_strong_4_2(volatile _Uint4_t *_Tgt, _Uint2_t *_Exp, _Uint2_t _Value, memory_order _Order1, memory_order _Order2) { return __ghs_atomic_compare_exchange_32_16((_Uint4_t *)_Tgt, _Exp, _Value, false, _Order1, _Order2); } #endif /* _ATOMIC_MINBYTES_LOCK_FREE == 4 */ __INLINE int _Atomic_compare_exchange_weak_4(volatile _Uint4_t *_Tgt, _Uint4_t *_Exp, _Uint4_t _Value, memory_order _Order1, memory_order _Order2) { return __ghs_atomic_compare_exchange_32((_Uint4_t *)_Tgt, _Exp, _Value, true, _Order1, _Order2); } #if (_ATOMIC_MINBYTES_LOCK_FREE == 4) __INLINE int _Atomic_compare_exchange_weak_4_1(volatile _Uint4_t *_Tgt, _Uint1_t *_Exp, _Uint1_t _Value, memory_order _Order1, memory_order _Order2) { return __ghs_atomic_compare_exchange_32_8((_Uint4_t *)_Tgt, _Exp, _Value, true, _Order1, _Order2); } __INLINE int _Atomic_compare_exchange_weak_4_2(volatile _Uint4_t *_Tgt, _Uint2_t *_Exp, _Uint2_t _Value, memory_order _Order1, memory_order _Order2) { return __ghs_atomic_compare_exchange_32_16((_Uint4_t *)_Tgt, _Exp, _Value, true, _Order1, _Order2); } #endif /* _ATOMIC_MINBYTES_LOCK_FREE == 4 */ __INLINE _Uint4_t _Atomic_fetch_add_4(volatile _Uint4_t *_Tgt, _Uint4_t _Value, memory_order _Order) { return __ghs_atomic_fetch_add_32((_Uint4_t *)_Tgt, _Value, _Order); } __INLINE _Uint4_t _Atomic_fetch_sub_4(volatile _Uint4_t *_Tgt, _Uint4_t _Value, memory_order _Order) { return __ghs_atomic_fetch_sub_32((_Uint4_t *)_Tgt, _Value, _Order); } __INLINE _Uint4_t _Atomic_fetch_and_4(volatile _Uint4_t *_Tgt, _Uint4_t _Value, memory_order _Order) { return __ghs_atomic_fetch_and_32((_Uint4_t *)_Tgt, _Value, _Order); } __INLINE _Uint4_t _Atomic_fetch_or_4(volatile _Uint4_t *_Tgt, _Uint4_t _Value, memory_order _Order) { return __ghs_atomic_fetch_or_32((_Uint4_t *)_Tgt, _Value, _Order); } __INLINE _Uint4_t _Atomic_fetch_xor_4(volatile _Uint4_t *_Tgt, _Uint4_t _Value, memory_order _Order) { return __ghs_atomic_fetch_xor_32((_Uint4_t *)_Tgt, _Value, _Order); } #if (_ATOMIC_MINBYTES_LOCK_FREE == 4) __INLINE _Uint4_t _Atomic_fetch_add_4_1(volatile _Uint4_t *_Tgt, _Uint4_t _Value, memory_order _Order) { return __ghs_atomic_fetch_add_32_8((_Uint4_t *)_Tgt, _Value, _Order); } __INLINE _Uint4_t _Atomic_fetch_sub_4_1(volatile _Uint4_t *_Tgt, _Uint4_t _Value, memory_order _Order) { return __ghs_atomic_fetch_sub_32_8((_Uint4_t *)_Tgt, _Value, _Order); } __INLINE _Uint4_t _Atomic_fetch_and_4_1(volatile _Uint4_t *_Tgt, _Uint4_t _Value, memory_order _Order) { return __ghs_atomic_fetch_and_32_8((_Uint4_t *)_Tgt, _Value, _Order); } __INLINE _Uint4_t _Atomic_fetch_or_4_1(volatile _Uint4_t *_Tgt, _Uint4_t _Value, memory_order _Order) { return __ghs_atomic_fetch_or_32_8((_Uint4_t *)_Tgt, _Value, _Order); } __INLINE _Uint4_t _Atomic_fetch_xor_4_1(volatile _Uint4_t *_Tgt, _Uint4_t _Value, memory_order _Order) { return __ghs_atomic_fetch_xor_32_8((_Uint4_t *)_Tgt, _Value, _Order); } __INLINE _Uint4_t _Atomic_fetch_add_4_2(volatile _Uint4_t *_Tgt, _Uint4_t _Value, memory_order _Order) { return __ghs_atomic_fetch_add_32_16((_Uint4_t *)_Tgt, _Value, _Order); } __INLINE _Uint4_t _Atomic_fetch_sub_4_2(volatile _Uint4_t *_Tgt, _Uint4_t _Value, memory_order _Order) { return __ghs_atomic_fetch_sub_32_16((_Uint4_t *)_Tgt, _Value, _Order); } __INLINE _Uint4_t _Atomic_fetch_and_4_2(volatile _Uint4_t *_Tgt, _Uint4_t _Value, memory_order _Order) { return __ghs_atomic_fetch_and_32_16((_Uint4_t *)_Tgt, _Value, _Order); } __INLINE _Uint4_t _Atomic_fetch_or_4_2(volatile _Uint4_t *_Tgt, _Uint4_t _Value, memory_order _Order) { return __ghs_atomic_fetch_or_32_16((_Uint4_t *)_Tgt, _Value, _Order); } __INLINE _Uint4_t _Atomic_fetch_xor_4_2(volatile _Uint4_t *_Tgt, _Uint4_t _Value, memory_order _Order) { return __ghs_atomic_fetch_xor_32_16((_Uint4_t *)_Tgt, _Value, _Order); } #endif /* _ATOMIC_MINBYTES_LOCK_FREE == 4 */ #endif /* (_ATOMIC_MAXBYTES_LOCK_FREE >= 4) */ #if (_ATOMIC_MAXBYTES_LOCK_FREE >= 8) __INLINE void _Atomic_store_8(volatile _Uint8_t *_Tgt, _Uint8_t _Value, memory_order _Order) { __ghs_atomic_store_64((_Uint8_t *)_Tgt, _Value, _Order); } __INLINE _Uint8_t _Atomic_load_8(volatile _Uint8_t *_Tgt, memory_order _Order) { return __ghs_atomic_load_64((_Uint8_t *)_Tgt, _Order); } __INLINE _Uint8_t _Atomic_exchange_8(volatile _Uint8_t *_Tgt, _Uint8_t _Value, memory_order _Order) { return __ghs_atomic_exchange_64((_Uint8_t *)_Tgt, _Value, _Order); } __INLINE int _Atomic_compare_exchange_strong_8(volatile _Uint8_t *_Tgt, _Uint8_t *_Exp, _Uint8_t _Value, memory_order _Order1, memory_order _Order2) { return __ghs_atomic_compare_exchange_64((_Uint8_t *)_Tgt, _Exp, _Value, false, _Order1, _Order2); } __INLINE int _Atomic_compare_exchange_weak_8(volatile _Uint8_t *_Tgt, _Uint8_t *_Exp, _Uint8_t _Value, memory_order _Order1, memory_order _Order2) { return __ghs_atomic_compare_exchange_64((_Uint8_t *)_Tgt, _Exp, _Value, true, _Order1, _Order2); } __INLINE _Uint8_t _Atomic_fetch_add_8(volatile _Uint8_t *_Tgt, _Uint8_t _Value, memory_order _Order) { return __ghs_atomic_fetch_add_64((_Uint8_t *)_Tgt, _Value, _Order); } __INLINE _Uint8_t _Atomic_fetch_sub_8(volatile _Uint8_t *_Tgt, _Uint8_t _Value, memory_order _Order) { return __ghs_atomic_fetch_sub_64((_Uint8_t *)_Tgt, _Value, _Order); } __INLINE _Uint8_t _Atomic_fetch_and_8(volatile _Uint8_t *_Tgt, _Uint8_t _Value, memory_order _Order) { return __ghs_atomic_fetch_and_64((_Uint8_t *)_Tgt, _Value, _Order); } __INLINE _Uint8_t _Atomic_fetch_or_8(volatile _Uint8_t *_Tgt, _Uint8_t _Value, memory_order _Order) { return __ghs_atomic_fetch_or_64((_Uint8_t *)_Tgt, _Value, _Order); } __INLINE _Uint8_t _Atomic_fetch_xor_8(volatile _Uint8_t *_Tgt, _Uint8_t _Value, memory_order _Order) { return __ghs_atomic_fetch_xor_64((_Uint8_t *)_Tgt, _Value, _Order); } #endif /* (_ATOMIC_MAXBYTES_LOCK_FREE >= 8) */ #define __APPEND2(A,B) A##B #define __APPEND(A,B) __APPEND2(A,B) #if !_ATOMIC_FLAG_USES_LOCK __INLINE int _Atomic_flag_test_and_set(volatile _Atomic_flag_t *_Flag, memory_order _Order) { return __APPEND(_Atomic_exchange_,_ATOMIC_FLAG_SIZE)(_Flag, 1, _Order); } __INLINE void _Atomic_flag_clear(volatile _Atomic_flag_t *_Flag, memory_order _Order) { __APPEND(_Atomic_store_,_ATOMIC_FLAG_SIZE)(_Flag, 0, _Order); } #endif /* _ATOMIC_FLAG_USES_LOCK */ #if !_ATOMIC_FENCE_USES_LOCK __INLINE void _Atomic_thread_fence(memory_order _Order) { #if defined(__ARM__) || defined(__ARM64__) || defined(__i386__) \ || defined(__RISCV__) __ghs_atomic_thread_fence(_Order); #else /* !defined(__ARM__) */ if (_Order != memory_order_relaxed) { #if defined(_ATOMIC_FENCE_USES_EXCHANGE) static _Atomic_flag_t guard; __APPEND(_Atomic_exchange_,_ATOMIC_FLAG_SIZE)(&guard, 0, _Order); #else __GHS_ATOMIC_FENCE(_POS_FENCE, _LDST_LOAD, _Order, 0); #endif /* !defined(_ATOMIC_FENCE_USES_EXCHANGE) */ } #endif /* !defined(__ARM__) */ } __INLINE void _Atomic_signal_fence(memory_order _Order) { __schedule_barrier(); } #endif /* _ATOMIC_FENCE_USES_LOCK */ #undef __APPEND2 #undef __APPEND _STD_END #undef __INLINE #endif /* __OUT_OF_LINE_ATOMICS */ #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* __GHS_ATOMIC_IMPL_H */