Skip to content

Commit a24a89c

Browse files
committed
Merge branch 'REL9_5_STABLE' into PGPRO9_5
2 parents fd5f28d + f998948 commit a24a89c

File tree

1 file changed

+22
-4
lines changed

1 file changed

+22
-4
lines changed

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

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,22 @@ static inline bool
4646
pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr,
4747
uint32 *expected, uint32 newval)
4848
{
49+
bool ret;
50+
51+
/*
52+
* atomics.h specifies sequential consistency ("full barrier semantics")
53+
* for this interface. Since "lwsync" provides acquire/release
54+
* consistency only, do not use it here. GCC atomics observe the same
55+
* restriction; see its rs6000_pre_atomic_barrier().
56+
*/
57+
__asm__ __volatile__ (" sync \n" ::: "memory");
58+
4959
/*
5060
* XXX: __compare_and_swap is defined to take signed parameters, but that
5161
* shouldn't matter since we don't perform any arithmetic operations.
5262
*/
53-
bool ret = __compare_and_swap((volatile int*)&ptr->value,
54-
(int *)expected, (int)newval);
63+
ret = __compare_and_swap((volatile int*)&ptr->value,
64+
(int *)expected, (int)newval);
5565

5666
/*
5767
* xlc's documentation tells us:
@@ -69,6 +79,10 @@ pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr,
6979
static inline uint32
7080
pg_atomic_fetch_add_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_)
7181
{
82+
/*
83+
* __fetch_and_add() emits a leading "sync" and trailing "isync", thereby
84+
* providing sequential consistency. This is undocumented.
85+
*/
7286
return __fetch_and_add((volatile int *)&ptr->value, add_);
7387
}
7488

@@ -79,8 +93,12 @@ static inline bool
7993
pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr,
8094
uint64 *expected, uint64 newval)
8195
{
82-
bool ret = __compare_and_swaplp((volatile long*)&ptr->value,
83-
(long *)expected, (long)newval);
96+
bool ret;
97+
98+
__asm__ __volatile__ (" sync \n" ::: "memory");
99+
100+
ret = __compare_and_swaplp((volatile long*)&ptr->value,
101+
(long *)expected, (long)newval);
84102

85103
__isync();
86104

0 commit comments

Comments
 (0)