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

Commit e09db94

Browse files
committed
Use more of gcc's __sync_fetch_and_xxx builtin functions for atomic ops.
In addition to __sync_fetch_and_add, gcc offers __sync_fetch_and_sub, __sync_fetch_and_and, and __sync_fetch_and_or, which correspond directly to primitive atomic ops that we want. Testing shows that in some cases they generate better code than our generic implementations, so use them. We've assumed that configure's test for __sync_val_compare_and_swap is sufficient to allow assuming that __sync_fetch_and_add is available, so make the same assumption for these functions. Should that prove to be wrong, we can add more configure tests. Yura Sokolov, reviewed by Jesper Pedersen and myself Discussion: https://postgr.es/m/7f65886daca545067f82bf2b463b218d@postgrespro.ru
1 parent e530be9 commit e09db94

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

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

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr,
176176
}
177177
#endif
178178

179+
/* if we have 32-bit __sync_val_compare_and_swap, assume we have these too: */
180+
179181
#if !defined(PG_HAVE_ATOMIC_FETCH_ADD_U32) && defined(HAVE_GCC__SYNC_INT32_CAS)
180182
#define PG_HAVE_ATOMIC_FETCH_ADD_U32
181183
static inline uint32
@@ -185,6 +187,33 @@ pg_atomic_fetch_add_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_)
185187
}
186188
#endif
187189

190+
#if !defined(PG_HAVE_ATOMIC_FETCH_SUB_U32) && defined(HAVE_GCC__SYNC_INT32_CAS)
191+
#define PG_HAVE_ATOMIC_FETCH_SUB_U32
192+
static inline uint32
193+
pg_atomic_fetch_sub_u32_impl(volatile pg_atomic_uint32 *ptr, int32 sub_)
194+
{
195+
return __sync_fetch_and_sub(&ptr->value, sub_);
196+
}
197+
#endif
198+
199+
#if !defined(PG_HAVE_ATOMIC_FETCH_AND_U32) && defined(HAVE_GCC__SYNC_INT32_CAS)
200+
#define PG_HAVE_ATOMIC_FETCH_AND_U32
201+
static inline uint32
202+
pg_atomic_fetch_and_u32_impl(volatile pg_atomic_uint32 *ptr, uint32 and_)
203+
{
204+
return __sync_fetch_and_and(&ptr->value, and_);
205+
}
206+
#endif
207+
208+
#if !defined(PG_HAVE_ATOMIC_FETCH_OR_U32) && defined(HAVE_GCC__SYNC_INT32_CAS)
209+
#define PG_HAVE_ATOMIC_FETCH_OR_U32
210+
static inline uint32
211+
pg_atomic_fetch_or_u32_impl(volatile pg_atomic_uint32 *ptr, uint32 or_)
212+
{
213+
return __sync_fetch_and_or(&ptr->value, or_);
214+
}
215+
#endif
216+
188217

189218
#if !defined(PG_DISABLE_64_BIT_ATOMICS)
190219

@@ -214,6 +243,8 @@ pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr,
214243
}
215244
#endif
216245

246+
/* if we have 64-bit __sync_val_compare_and_swap, assume we have these too: */
247+
217248
#if !defined(PG_HAVE_ATOMIC_FETCH_ADD_U64) && defined(HAVE_GCC__SYNC_INT64_CAS)
218249
#define PG_HAVE_ATOMIC_FETCH_ADD_U64
219250
static inline uint64
@@ -223,6 +254,33 @@ pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_)
223254
}
224255
#endif
225256

257+
#if !defined(PG_HAVE_ATOMIC_FETCH_SUB_U64) && defined(HAVE_GCC__SYNC_INT64_CAS)
258+
#define PG_HAVE_ATOMIC_FETCH_SUB_U64
259+
static inline uint64
260+
pg_atomic_fetch_sub_u64_impl(volatile pg_atomic_uint64 *ptr, int64 sub_)
261+
{
262+
return __sync_fetch_and_sub(&ptr->value, sub_);
263+
}
264+
#endif
265+
266+
#if !defined(PG_HAVE_ATOMIC_FETCH_AND_U64) && defined(HAVE_GCC__SYNC_INT64_CAS)
267+
#define PG_HAVE_ATOMIC_FETCH_AND_U64
268+
static inline uint64
269+
pg_atomic_fetch_and_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 and_)
270+
{
271+
return __sync_fetch_and_and(&ptr->value, and_);
272+
}
273+
#endif
274+
275+
#if !defined(PG_HAVE_ATOMIC_FETCH_OR_U64) && defined(HAVE_GCC__SYNC_INT64_CAS)
276+
#define PG_HAVE_ATOMIC_FETCH_OR_U64
277+
static inline uint64
278+
pg_atomic_fetch_or_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 or_)
279+
{
280+
return __sync_fetch_and_or(&ptr->value, or_);
281+
}
282+
#endif
283+
226284
#endif /* !defined(PG_DISABLE_64_BIT_ATOMICS) */
227285

228286
#endif /* defined(HAVE_ATOMICS) */

0 commit comments

Comments
 (0)