Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit dd50f1a

Browse filesBrowse files
committed
Replace xlc __fetch_and_add() with inline asm.
PostgreSQL has been unusable when built with xlc 13 and newer, which are incompatible with our use of __fetch_and_add(). Back-patch to 9.5, which introduced pg_atomic_fetch_add_u32(). Reviewed by Tom Lane. Discussion: https://postgr.es/m/20190831071157.GA3251746@rfd.leadboat.com
1 parent f380c51 commit dd50f1a
Copy full SHA for dd50f1a

File tree

Expand file treeCollapse file tree

1 file changed

+35
-4
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+35
-4
lines changed

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

Copy file name to clipboardExpand all lines: src/include/port/atomics/generic-xlc.h
+35-4Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,27 @@ pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr,
7373
static inline uint32
7474
pg_atomic_fetch_add_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_)
7575
{
76+
uint32 _t;
77+
uint32 res;
78+
7679
/*
77-
* __fetch_and_add() emits a leading "sync" and trailing "isync", thereby
78-
* providing sequential consistency. This is undocumented.
80+
* xlc has a no-longer-documented __fetch_and_add() intrinsic. In xlc
81+
* 12.01.0000.0000, it emits a leading "sync" and trailing "isync". In
82+
* xlc 13.01.0003.0004, it emits neither. Hence, using the intrinsic
83+
* would add redundant syncs on xlc 12.
7984
*/
80-
return __fetch_and_add((volatile int *)&ptr->value, add_);
85+
__asm__ __volatile__(
86+
" sync \n"
87+
" lwarx %1,0,%4 \n"
88+
" add %0,%1,%3 \n"
89+
" stwcx. %0,0,%4 \n"
90+
" bne $-12 \n" /* branch to lwarx */
91+
" isync \n"
92+
: "=&r"(_t), "=&r"(res), "+m"(ptr->value)
93+
: "r"(add_), "r"(&ptr->value)
94+
: "memory", "cc");
95+
96+
return res;
8197
}
8298

8399
#ifdef PG_HAVE_ATOMIC_U64_SUPPORT
@@ -103,7 +119,22 @@ pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr,
103119
static inline uint64
104120
pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_)
105121
{
106-
return __fetch_and_addlp((volatile long *)&ptr->value, add_);
122+
uint64 _t;
123+
uint64 res;
124+
125+
/* Like u32, but s/lwarx/ldarx/; s/stwcx/stdcx/ */
126+
__asm__ __volatile__(
127+
" sync \n"
128+
" ldarx %1,0,%4 \n"
129+
" add %0,%1,%3 \n"
130+
" stdcx. %0,0,%4 \n"
131+
" bne $-12 \n" /* branch to ldarx */
132+
" isync \n"
133+
: "=&r"(_t), "=&r"(res), "+m"(ptr->value)
134+
: "r"(add_), "r"(&ptr->value)
135+
: "memory", "cc");
136+
137+
return res;
107138
}
108139

109140
#endif /* PG_HAVE_ATOMIC_U64_SUPPORT */

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.