diff options
author | Andres Freund | 2014-09-25 20:45:08 +0000 |
---|---|---|
committer | Andres Freund | 2014-10-01 16:01:47 +0000 |
commit | d871e5f720000b7ca3de795f37e3f5307d776c3c (patch) | |
tree | bebbffe23cbd7f736624e996407a188131b440ff | |
parent | eedffb0e25b6cc1fa37dce9c8b548605e46a26c5 (diff) |
Add pg_atomic_fetch_add_until_u32().rwlock-contention
-rw-r--r-- | src/include/port/atomics.h | 17 | ||||
-rw-r--r-- | src/include/port/atomics/generic.h | 24 |
2 files changed, 41 insertions, 0 deletions
diff --git a/src/include/port/atomics.h b/src/include/port/atomics.h index 5893543768..2aebbf7186 100644 --- a/src/include/port/atomics.h +++ b/src/include/port/atomics.h @@ -135,6 +135,8 @@ STATIC_IF_INLINE_DECLARE uint32 pg_atomic_fetch_and_u32(volatile pg_atomic_uint3 STATIC_IF_INLINE_DECLARE uint32 pg_atomic_fetch_or_u32(volatile pg_atomic_uint32 *ptr, uint32 or_); STATIC_IF_INLINE_DECLARE uint32 pg_atomic_add_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 add_); STATIC_IF_INLINE_DECLARE uint32 pg_atomic_sub_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 sub_); +STATIC_IF_INLINE_DECLARE uint32 pg_atomic_fetch_add_until_u32(volatile pg_atomic_uint32 *ptr, + int32 add_, uint32 until); #ifdef PG_HAVE_ATOMIC_U64_SUPPORT @@ -431,6 +433,21 @@ pg_atomic_sub_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 sub_) return pg_atomic_sub_fetch_u32_impl(ptr, sub_); } +/* + * pg_fetch_add_until_u32 - saturated addition to variable + * + * Returns the the value of ptr after the arithmetic operation. + * + * Full barrier semantics. + */ +STATIC_IF_INLINE uint32 +pg_atomic_fetch_add_until_u32(volatile pg_atomic_uint32 *ptr, int32 add_, + uint32 until) +{ + AssertPointerAlignment(ptr, 4); + return pg_atomic_fetch_add_until_u32_impl(ptr, add_, until); +} + /* ---- * The 64 bit operations have the same semantics as their 32bit counterparts * if they are available. Check the corresponding 32bit function for diff --git a/src/include/port/atomics/generic.h b/src/include/port/atomics/generic.h index fa751237a5..4d07b82cb6 100644 --- a/src/include/port/atomics/generic.h +++ b/src/include/port/atomics/generic.h @@ -248,6 +248,30 @@ pg_atomic_sub_fetch_u32_impl(volatile pg_atomic_uint32 *ptr, int32 sub_) } #endif +#if !defined(PG_HAVE_ATOMIC_FETCH_ADD_UNTIL_U32) && defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32) +#define PG_HAVE_ATOMIC_FETCH_ADD_UNTIL_U32 +static inline uint32 +pg_atomic_fetch_add_until_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_, uint32 until) +{ + uint32 old; + while (true) + { + uint32 new_val; + old = pg_atomic_read_u32_impl(ptr); + if (old >= until) + break; + + new_val = old + add_; + if (new_val > until) + new_val = until; + + if (pg_atomic_compare_exchange_u32_impl(ptr, &old, new_val)) + break; + } + return old; +} +#endif + #ifdef PG_HAVE_ATOMIC_U64_SUPPORT #if !defined(PG_HAVE_ATOMIC_EXCHANGE_U64) && defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64) |