diff --git a/src/include/port/atomics/arch-x86.h b/src/include/port/atomics/arch-x86.h index 11a891c865d6426d4a71a7b7113e88d5e29d848b..691b1e7d67665eb623ca1faa8724b91ed22e44cf 100644 --- a/src/include/port/atomics/arch-x86.h +++ b/src/include/port/atomics/arch-x86.h @@ -78,6 +78,7 @@ typedef struct pg_atomic_uint64 #endif #endif /* defined(HAVE_ATOMICS) */ + #endif /* defined(__GNUC__) && !defined(__INTEL_COMPILER) */ #if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) @@ -160,6 +161,18 @@ pg_atomic_test_set_flag_impl(volatile pg_atomic_flag *ptr) return _res == 0; } +#define PG_HAVE_ATOMIC_CLEAR_FLAG +static inline void +pg_atomic_clear_flag_impl(volatile pg_atomic_flag *ptr) +{ + /* + * On a TSO architecture like x86 it's sufficient to use a compiler + * barrier to achieve release semantics. + */ + __asm__ __volatile__("" ::: "memory"); + ptr->value = 0; +} + #define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32 static inline bool pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr, diff --git a/src/include/port/atomics/generic-acc.h b/src/include/port/atomics/generic-acc.h index 627e2dfcb5e134c7d62431e1bd2b44a27bc27a34..8983b1cda4b1828a3a263dbb83131e0c494f19bc 100644 --- a/src/include/port/atomics/generic-acc.h +++ b/src/include/port/atomics/generic-acc.h @@ -25,6 +25,10 @@ #include <machine/sys/inline.h> +#define pg_compiler_barrier_impl() _Asm_sched_fence() + +#if defined(HAVE_ATOMICS) + /* IA64 always has 32/64 bit atomics */ #define PG_HAVE_ATOMIC_U32_SUPPORT @@ -39,10 +43,13 @@ typedef struct pg_atomic_uint64 volatile uint64 value; } pg_atomic_uint64; -#define pg_compiler_barrier_impl() _Asm_sched_fence() +#endif /* defined(HAVE_ATOMICS) */ + #if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) +#if defined(HAVE_ATOMICS) + #define MINOR_FENCE (_Asm_fence) (_UP_CALL_FENCE | _UP_SYS_FENCE | \ _DOWN_CALL_FENCE | _DOWN_SYS_FENCE ) @@ -96,4 +103,6 @@ pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr, #undef MINOR_FENCE +#endif /* defined(HAVE_ATOMICS) */ + #endif /* defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) */ diff --git a/src/include/port/atomics/generic-gcc.h b/src/include/port/atomics/generic-gcc.h index 6a2373079b08db1bc8d413c29e77a9245867d9db..ecabef3144b20a83b4d4ee4d7506f09a3615e30e 100644 --- a/src/include/port/atomics/generic-gcc.h +++ b/src/include/port/atomics/generic-gcc.h @@ -40,19 +40,19 @@ * definitions where possible, and use this only as a fallback. */ #if !defined(pg_memory_barrier_impl) -# if defined(HAVE_GCC__ATOMIC_INT64_CAS) +# if defined(HAVE_GCC__ATOMIC_INT32_CAS) # define pg_memory_barrier_impl() __atomic_thread_fence(__ATOMIC_SEQ_CST) # elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) # define pg_memory_barrier_impl() __sync_synchronize() # endif #endif /* !defined(pg_memory_barrier_impl) */ -#if !defined(pg_read_barrier_impl) && defined(HAVE_GCC__ATOMIC_INT64_CAS) +#if !defined(pg_read_barrier_impl) && defined(HAVE_GCC__ATOMIC_INT32_CAS) /* acquire semantics include read barrier semantics */ # define pg_read_barrier_impl() __atomic_thread_fence(__ATOMIC_ACQUIRE) #endif -#if !defined(pg_write_barrier_impl) && defined(HAVE_GCC__ATOMIC_INT64_CAS) +#if !defined(pg_write_barrier_impl) && defined(HAVE_GCC__ATOMIC_INT32_CAS) /* release semantics include write barrier semantics */ # define pg_write_barrier_impl() __atomic_thread_fence(__ATOMIC_RELEASE) #endif @@ -139,13 +139,7 @@ pg_atomic_unlocked_test_flag_impl(volatile pg_atomic_flag *ptr) static inline void pg_atomic_clear_flag_impl(volatile pg_atomic_flag *ptr) { - /* - * XXX: It would be nicer to use __sync_lock_release here, but gcc insists - * on making that an atomic op which is far to expensive and a stronger - * guarantee than what we actually need. - */ - pg_write_barrier_impl(); - ptr->value = 0; + __sync_lock_release(&ptr->value); } #endif diff --git a/src/include/port/atomics/generic-msvc.h b/src/include/port/atomics/generic-msvc.h index 747daa0a760e42554628a1c9312a48aa156666fa..419cbc389561211b189bf058b46bd73fa7e6b44c 100644 --- a/src/include/port/atomics/generic-msvc.h +++ b/src/include/port/atomics/generic-msvc.h @@ -32,6 +32,8 @@ #define pg_memory_barrier_impl() MemoryBarrier() #endif +#if defined(HAVE_ATOMICS) + #define PG_HAVE_ATOMIC_U32_SUPPORT typedef struct pg_atomic_uint32 { @@ -44,9 +46,13 @@ typedef struct pg_atomic_uint64 volatile uint64 value; } pg_atomic_uint64; +#endif /* defined(HAVE_ATOMICS) */ + #if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) +#if defined(HAVE_ATOMICS) + #define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32 static inline bool pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr, @@ -100,4 +106,6 @@ pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_) } #endif /* _WIN64 */ +#endif /* HAVE_ATOMICS */ + #endif /* defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) */ diff --git a/src/include/port/atomics/generic-sunpro.h b/src/include/port/atomics/generic-sunpro.h index b71b5230d3c9ec2350225b217e230e8c7956635b..77d3ebe0031cd0b1e8847d348d6527228d7e34fc 100644 --- a/src/include/port/atomics/generic-sunpro.h +++ b/src/include/port/atomics/generic-sunpro.h @@ -17,6 +17,8 @@ * ------------------------------------------------------------------------- */ +#if defined(HAVE_ATOMICS) + /* Older versions of the compiler don't have atomic.h... */ #ifdef HAVE_ATOMIC_H @@ -36,9 +38,13 @@ typedef struct pg_atomic_uint64 #endif /* HAVE_ATOMIC_H */ +#endif /* defined(HAVE_ATOMICS) */ + #if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) +#if defined(HAVE_ATOMICS) + #ifdef HAVE_ATOMIC_H #define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32 @@ -71,4 +77,6 @@ pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr, #endif /* HAVE_ATOMIC_H */ +#endif /* defined(HAVE_ATOMICS) */ + #endif /* defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) */ diff --git a/src/include/port/atomics/generic-xlc.h b/src/include/port/atomics/generic-xlc.h index 579554d8a67cf6486e358f20f52fc43148e236f3..1cc7ba28cde7075f010f74cb4d20778dff22561c 100644 --- a/src/include/port/atomics/generic-xlc.h +++ b/src/include/port/atomics/generic-xlc.h @@ -16,6 +16,8 @@ * ------------------------------------------------------------------------- */ +#if defined(HAVE_ATOMICS) + #include <atomic.h> #define PG_HAVE_ATOMIC_U32_SUPPORT @@ -35,8 +37,12 @@ typedef struct pg_atomic_uint64 #endif /* __64BIT__ */ +#endif /* defined(HAVE_ATOMICS) */ + #if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) +#if defined(HAVE_ATOMICS) + #define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32 static inline bool pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr, @@ -69,7 +75,6 @@ pg_atomic_fetch_add_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_) { return __fetch_and_add(&ptr->value, add_); } -#endif #ifdef PG_HAVE_ATOMIC_U64_SUPPORT @@ -96,8 +101,9 @@ pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_) { return __fetch_and_addlp(&ptr->value, add_); } -#endif #endif /* PG_HAVE_ATOMIC_U64_SUPPORT */ +#endif /* defined(HAVE_ATOMICS) */ + #endif /* defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) */