Remove bogus assertion in pg_atomic_monotonic_advance_u64
authorAlvaro Herrera <[email protected]>
Thu, 4 Jul 2024 11:25:31 +0000 (13:25 +0200)
committerAlvaro Herrera <[email protected]>
Thu, 4 Jul 2024 11:25:31 +0000 (13:25 +0200)
This code wanted to ensure that the 'exchange' variable passed to
pg_atomic_compare_exchange_u64 has correct alignment, but apparently
platforms don't actually require anything that doesn't come naturally.

While messing with pg_atomic_monotonic_advance_u64: instead of using
Max() to determine the value to return, just use
pg_atomic_compare_exchange_u64()'s return value to decide; also, use
pg_atomic_compare_exchange_u64 instead of the _impl version; also remove
the unnecessary underscore at the end of variable name "target".

Backpatch to 17, where this code was introduced by commit bf3ff7bf83bc.

Reported-by: Alexander Lakhin <[email protected]>
Discussion: https://postgr.es/m/36796438-a718-cf9b-2071-b2c1b947c1b5@gmail.com

src/include/port/atomics.h
src/include/port/atomics/arch-ppc.h
src/include/port/atomics/arch-x86.h
src/include/port/atomics/generic-gcc.h
src/include/port/atomics/generic-sunpro.h

index c911c6b9564daa8f7b4e66f0c045d3acbc6d16db..f6fa432d2dfde74f9930e0d2a450e6322fa2b0d3 100644 (file)
@@ -507,7 +507,6 @@ pg_atomic_compare_exchange_u64(volatile pg_atomic_uint64 *ptr,
 {
 #ifndef PG_HAVE_ATOMIC_U64_SIMULATION
    AssertPointerAlignment(ptr, 8);
-   AssertPointerAlignment(expected, 8);
 #endif
    return pg_atomic_compare_exchange_u64_impl(ptr, expected, newval);
 }
@@ -576,7 +575,7 @@ pg_atomic_sub_fetch_u64(volatile pg_atomic_uint64 *ptr, int64 sub_)
  * Full barrier semantics (even when value is unchanged).
  */
 static inline uint64
-pg_atomic_monotonic_advance_u64(volatile pg_atomic_uint64 *ptr, uint64 target_)
+pg_atomic_monotonic_advance_u64(volatile pg_atomic_uint64 *ptr, uint64 target)
 {
    uint64      currval;
 
@@ -585,23 +584,19 @@ pg_atomic_monotonic_advance_u64(volatile pg_atomic_uint64 *ptr, uint64 target_)
 #endif
 
    currval = pg_atomic_read_u64_impl(ptr);
-   if (currval >= target_)
+   if (currval >= target)
    {
        pg_memory_barrier();
        return currval;
    }
 
-#ifndef PG_HAVE_ATOMIC_U64_SIMULATION
-   AssertPointerAlignment(&currval, 8);
-#endif
-
-   while (currval < target_)
+   while (currval < target)
    {
-       if (pg_atomic_compare_exchange_u64_impl(ptr, &currval, target_))
-           break;
+       if (pg_atomic_compare_exchange_u64(ptr, &currval, target))
+           return target;
    }
 
-   return Max(target_, currval);
+   return currval;
 }
 
 #undef INSIDE_ATOMICS_H
index 94ba2597fb7f1dd2faaa3e96fd77021ff2261d39..edaab7c8957fc626cd8fb9103187fd5244816191 100644 (file)
@@ -173,6 +173,8 @@ pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr,
    uint32 condition_register;
    bool ret;
 
+   AssertPointerAlignment(expected, 8);
+
    /* Like u32, but s/lwarx/ldarx/; s/stwcx/stdcx/; s/cmpw/cmpd/ */
 #ifdef HAVE_I_CONSTRAINT__BUILTIN_CONSTANT_P
    if (__builtin_constant_p(*expected) &&
index 3efa79dc3df3a67569843dfd1798556a4be3d93e..2a8eca30fcf9d0e58a0b225336d0efa5f1890450 100644 (file)
@@ -207,6 +207,8 @@ pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr,
 {
    char    ret;
 
+   AssertPointerAlignment(expected, 8);
+
    /*
     * Perform cmpxchg and use the zero flag which it implicitly sets when
     * equal to measure the success.
index 9d91370fa8cde316840248d1aefd5844d86acacb..872d2f02af4a2c37ac901f3b95e2fca4292ed597 100644 (file)
@@ -240,6 +240,7 @@ static inline bool
 pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr,
                                    uint64 *expected, uint64 newval)
 {
+   AssertPointerAlignment(expected, 8);
    return __atomic_compare_exchange_n(&ptr->value, expected, newval, false,
                                       __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
 }
@@ -253,6 +254,8 @@ pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr,
 {
    bool    ret;
    uint64  current;
+
+   AssertPointerAlignment(expected, 8);
    current = __sync_val_compare_and_swap(&ptr->value, *expected, newval);
    ret = current == *expected;
    *expected = current;
index e060c0868a963ec2c8c0db97ff63949b33f909fc..840a45e7788c7484a91e7304f7b5dbdd0ce0fd7f 100644 (file)
@@ -102,6 +102,7 @@ pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr,
    bool    ret;
    uint64  current;
 
+   AssertPointerAlignment(expected, 8);
    current = atomic_cas_64(&ptr->value, *expected, newval);
    ret = current == *expected;
    *expected = current;