From 630b329de06705c09ab2372f2fb8f102d1f1f701 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Sat, 28 Mar 2020 11:42:59 +1300 Subject: [PATCH v10 1/3] Add pg_atomic_unlocked_add_fetch_XXX(). Add a variant of pg_atomic_add_fetch_XXX with no barrier semantics, for cases where you only want to avoid the possibility that a concurrent pg_atomic_read_XXX() sees a torn/partial value. Discussion: https://postgr.es/m/CA%2BhUKGJ4VJN8ttxScUFM8dOKX0BrBiboo5uz1cq%3DAovOddfHpA%40mail.gmail.com --- src/include/port/atomics.h | 24 ++++++++++++++++++++++ src/include/port/atomics/generic.h | 33 ++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/include/port/atomics.h b/src/include/port/atomics.h index 4956ec55cb..2abb852893 100644 --- a/src/include/port/atomics.h +++ b/src/include/port/atomics.h @@ -389,6 +389,21 @@ pg_atomic_add_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 add_) return pg_atomic_add_fetch_u32_impl(ptr, add_); } +/* + * pg_atomic_unlocked_add_fetch_u32 - atomically add to variable + * + * Like pg_atomic_unlocked_write_u32, guarantees only that partial values + * cannot be observed. + * + * No barrier semantics. + */ +static inline uint32 +pg_atomic_unlocked_add_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 add_) +{ + AssertPointerAlignment(ptr, 4); + return pg_atomic_unlocked_add_fetch_u32_impl(ptr, add_); +} + /* * pg_atomic_sub_fetch_u32 - atomically subtract from variable * @@ -519,6 +534,15 @@ pg_atomic_sub_fetch_u64(volatile pg_atomic_uint64 *ptr, int64 sub_) return pg_atomic_sub_fetch_u64_impl(ptr, sub_); } +static inline uint64 +pg_atomic_unlocked_add_fetch_u64(volatile pg_atomic_uint64 *ptr, int64 add_) +{ +#ifndef PG_HAVE_ATOMIC_U64_SIMULATION + AssertPointerAlignment(ptr, 8); +#endif + return pg_atomic_unlocked_add_fetch_u64_impl(ptr, add_); +} + #undef INSIDE_ATOMICS_H #endif /* ATOMICS_H */ diff --git a/src/include/port/atomics/generic.h b/src/include/port/atomics/generic.h index d60a0d9e7f..3e1598d8ff 100644 --- a/src/include/port/atomics/generic.h +++ b/src/include/port/atomics/generic.h @@ -234,6 +234,16 @@ pg_atomic_add_fetch_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_) } #endif +#if !defined(PG_HAVE_ATOMIC_UNLOCKED_ADD_FETCH_U32) +#define PG_HAVE_ATOMIC_UNLOCKED_ADD_FETCH_U32 +static inline uint32 +pg_atomic_unlocked_add_fetch_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_) +{ + ptr->value += add_; + return ptr->value; +} +#endif + #if !defined(PG_HAVE_ATOMIC_SUB_FETCH_U32) && defined(PG_HAVE_ATOMIC_FETCH_SUB_U32) #define PG_HAVE_ATOMIC_SUB_FETCH_U32 static inline uint32 @@ -399,3 +409,26 @@ pg_atomic_sub_fetch_u64_impl(volatile pg_atomic_uint64 *ptr, int64 sub_) return pg_atomic_fetch_sub_u64_impl(ptr, sub_) - sub_; } #endif + +#if defined(PG_HAVE_8BYTE_SINGLE_COPY_ATOMICITY) && \ + !defined(PG_HAVE_ATOMIC_U64_SIMULATION) + +#ifndef PG_HAVE_ATOMIC_UNLOCKED_ADD_FETCH_U64 +#define PG_HAVE_ATOMIC_UNLOCKED_ADD_FETCH_U64 +static inline uint64 +pg_atomic_unlocked_add_fetch_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 val) +{ + ptr->value += val; + return ptr->value; +} +#endif + +#else + +static inline uint64 +pg_atomic_unlocked_add_fetch_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 val) +{ + return pg_atomic_add_fetch_u64_impl(ptr, val); +} + +#endif -- 2.20.1