Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f9f0741

Browse files
committed
Further atomic ops portability improvements and bug fixes.
* Don't play tricks for a more efficient pg_atomic_clear_flag() in the generic gcc implementation. The old version was broken on gcc < 4.7 on !x86 platforms. Per buildfarm member chipmunk. * Make usage of __atomic() fences depend on HAVE_GCC__ATOMIC_INT32_CAS instead of HAVE_GCC__ATOMIC_INT64_CAS - there's platforms with 32bit support that don't support 64bit atomics. * Blindly fix two superflous #endif in generic-xlc.h * Check for --disable-atomics in platforms but x86.
1 parent a30199b commit f9f0741

File tree

6 files changed

+51
-13
lines changed

6 files changed

+51
-13
lines changed

src/include/port/atomics/arch-x86.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ typedef struct pg_atomic_uint64
7878
#endif
7979

8080
#endif /* defined(HAVE_ATOMICS) */
81+
8182
#endif /* defined(__GNUC__) && !defined(__INTEL_COMPILER) */
8283

8384
#if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS)
@@ -160,6 +161,18 @@ pg_atomic_test_set_flag_impl(volatile pg_atomic_flag *ptr)
160161
return _res == 0;
161162
}
162163

164+
#define PG_HAVE_ATOMIC_CLEAR_FLAG
165+
static inline void
166+
pg_atomic_clear_flag_impl(volatile pg_atomic_flag *ptr)
167+
{
168+
/*
169+
* On a TSO architecture like x86 it's sufficient to use a compiler
170+
* barrier to achieve release semantics.
171+
*/
172+
__asm__ __volatile__("" ::: "memory");
173+
ptr->value = 0;
174+
}
175+
163176
#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32
164177
static inline bool
165178
pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr,

src/include/port/atomics/generic-acc.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525

2626
#include <machine/sys/inline.h>
2727

28+
#define pg_compiler_barrier_impl() _Asm_sched_fence()
29+
30+
#if defined(HAVE_ATOMICS)
31+
2832
/* IA64 always has 32/64 bit atomics */
2933

3034
#define PG_HAVE_ATOMIC_U32_SUPPORT
@@ -39,10 +43,13 @@ typedef struct pg_atomic_uint64
3943
volatile uint64 value;
4044
} pg_atomic_uint64;
4145

42-
#define pg_compiler_barrier_impl() _Asm_sched_fence()
46+
#endif /* defined(HAVE_ATOMICS) */
47+
4348

4449
#if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS)
4550

51+
#if defined(HAVE_ATOMICS)
52+
4653
#define MINOR_FENCE (_Asm_fence) (_UP_CALL_FENCE | _UP_SYS_FENCE | \
4754
_DOWN_CALL_FENCE | _DOWN_SYS_FENCE )
4855

@@ -96,4 +103,6 @@ pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr,
96103

97104
#undef MINOR_FENCE
98105

106+
#endif /* defined(HAVE_ATOMICS) */
107+
99108
#endif /* defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) */

src/include/port/atomics/generic-gcc.h

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,19 @@
4040
* definitions where possible, and use this only as a fallback.
4141
*/
4242
#if !defined(pg_memory_barrier_impl)
43-
# if defined(HAVE_GCC__ATOMIC_INT64_CAS)
43+
# if defined(HAVE_GCC__ATOMIC_INT32_CAS)
4444
# define pg_memory_barrier_impl() __atomic_thread_fence(__ATOMIC_SEQ_CST)
4545
# elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
4646
# define pg_memory_barrier_impl() __sync_synchronize()
4747
# endif
4848
#endif /* !defined(pg_memory_barrier_impl) */
4949

50-
#if !defined(pg_read_barrier_impl) && defined(HAVE_GCC__ATOMIC_INT64_CAS)
50+
#if !defined(pg_read_barrier_impl) && defined(HAVE_GCC__ATOMIC_INT32_CAS)
5151
/* acquire semantics include read barrier semantics */
5252
# define pg_read_barrier_impl() __atomic_thread_fence(__ATOMIC_ACQUIRE)
5353
#endif
5454

55-
#if !defined(pg_write_barrier_impl) && defined(HAVE_GCC__ATOMIC_INT64_CAS)
55+
#if !defined(pg_write_barrier_impl) && defined(HAVE_GCC__ATOMIC_INT32_CAS)
5656
/* release semantics include write barrier semantics */
5757
# define pg_write_barrier_impl() __atomic_thread_fence(__ATOMIC_RELEASE)
5858
#endif
@@ -139,13 +139,7 @@ pg_atomic_unlocked_test_flag_impl(volatile pg_atomic_flag *ptr)
139139
static inline void
140140
pg_atomic_clear_flag_impl(volatile pg_atomic_flag *ptr)
141141
{
142-
/*
143-
* XXX: It would be nicer to use __sync_lock_release here, but gcc insists
144-
* on making that an atomic op which is far to expensive and a stronger
145-
* guarantee than what we actually need.
146-
*/
147-
pg_write_barrier_impl();
148-
ptr->value = 0;
142+
__sync_lock_release(&ptr->value);
149143
}
150144
#endif
151145

src/include/port/atomics/generic-msvc.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#define pg_memory_barrier_impl() MemoryBarrier()
3333
#endif
3434

35+
#if defined(HAVE_ATOMICS)
36+
3537
#define PG_HAVE_ATOMIC_U32_SUPPORT
3638
typedef struct pg_atomic_uint32
3739
{
@@ -44,9 +46,13 @@ typedef struct pg_atomic_uint64
4446
volatile uint64 value;
4547
} pg_atomic_uint64;
4648

49+
#endif /* defined(HAVE_ATOMICS) */
50+
4751

4852
#if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS)
4953

54+
#if defined(HAVE_ATOMICS)
55+
5056
#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32
5157
static inline bool
5258
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_)
100106
}
101107
#endif /* _WIN64 */
102108

109+
#endif /* HAVE_ATOMICS */
110+
103111
#endif /* defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) */

src/include/port/atomics/generic-sunpro.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
* -------------------------------------------------------------------------
1818
*/
1919

20+
#if defined(HAVE_ATOMICS)
21+
2022
/* Older versions of the compiler don't have atomic.h... */
2123
#ifdef HAVE_ATOMIC_H
2224

@@ -36,9 +38,13 @@ typedef struct pg_atomic_uint64
3638

3739
#endif /* HAVE_ATOMIC_H */
3840

41+
#endif /* defined(HAVE_ATOMICS) */
42+
3943

4044
#if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS)
4145

46+
#if defined(HAVE_ATOMICS)
47+
4248
#ifdef HAVE_ATOMIC_H
4349

4450
#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32
@@ -71,4 +77,6 @@ pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr,
7177

7278
#endif /* HAVE_ATOMIC_H */
7379

80+
#endif /* defined(HAVE_ATOMICS) */
81+
7482
#endif /* defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) */

src/include/port/atomics/generic-xlc.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
* -------------------------------------------------------------------------
1717
*/
1818

19+
#if defined(HAVE_ATOMICS)
20+
1921
#include <atomic.h>
2022

2123
#define PG_HAVE_ATOMIC_U32_SUPPORT
@@ -35,8 +37,12 @@ typedef struct pg_atomic_uint64
3537

3638
#endif /* __64BIT__ */
3739

40+
#endif /* defined(HAVE_ATOMICS) */
41+
3842
#if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS)
3943

44+
#if defined(HAVE_ATOMICS)
45+
4046
#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32
4147
static inline bool
4248
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_)
6975
{
7076
return __fetch_and_add(&ptr->value, add_);
7177
}
72-
#endif
7378

7479
#ifdef PG_HAVE_ATOMIC_U64_SUPPORT
7580

@@ -96,8 +101,9 @@ pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_)
96101
{
97102
return __fetch_and_addlp(&ptr->value, add_);
98103
}
99-
#endif
100104

101105
#endif /* PG_HAVE_ATOMIC_U64_SUPPORT */
102106

107+
#endif /* defined(HAVE_ATOMICS) */
108+
103109
#endif /* defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) */

0 commit comments

Comments
 (0)