index 11a891c865d6426d4a71a7b7113e88d5e29d848b..691b1e7d67665eb623ca1faa8724b91ed22e44cf 100644 (file)
#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,
index 627e2dfcb5e134c7d62431e1bd2b44a27bc27a34..8983b1cda4b1828a3a263dbb83131e0c494f19bc 100644 (file)
#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
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) */
index 6a2373079b08db1bc8d413c29e77a9245867d9db..ecabef3144b20a83b4d4ee4d7506f09a3615e30e 100644 (file)
* 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
index 747daa0a760e42554628a1c9312a48aa156666fa..419cbc389561211b189bf058b46bd73fa7e6b44c 100644 (file)
#define pg_memory_barrier_impl() MemoryBarrier()
#endif
+#if defined(HAVE_ATOMICS)
+
#define PG_HAVE_ATOMIC_U32_SUPPORT
typedef struct pg_atomic_uint32
{
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) */
index b71b5230d3c9ec2350225b217e230e8c7956635b..77d3ebe0031cd0b1e8847d348d6527228d7e34fc 100644 (file)
* -------------------------------------------------------------------------
*/
+#if defined(HAVE_ATOMICS)
+
/* Older versions of the compiler don't have atomic.h... */
#ifdef HAVE_ATOMIC_H
#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) */
index 579554d8a67cf6486e358f20f52fc43148e236f3..1cc7ba28cde7075f010f74cb4d20778dff22561c 100644 (file)
* -------------------------------------------------------------------------
*/
+#if defined(HAVE_ATOMICS)
+
#include <atomic.h>
#define PG_HAVE_ATOMIC_U32_SUPPORT
#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) */