Rate This Document
Findability
Accuracy
Completeness
Readability

CAS

Perform the compare_and_swap operation on a 32-bit or 64-bit variable (a 32-bit variable is used as an example).

  • x86 platform
    static inline bool
    pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr,
                                                                            uint32 *expected, uint32 newval)
    {
            char    ret;
     
            /*
             * Perform cmpxchg and use the zero flag which it implicitly sets when
             * equal to measure the success.
             */
            __asm__ __volatile__(
                    "       lock                            \n"
                    "       cmpxchgl        %4,%5   \n"
                    "   setz                %2              \n"
    :               "=a" (*expected), "=m"(ptr->value), "=q" (ret)
    :               "a" (*expected), "r" (newval), "m"(ptr->value)
    :               "memory", "cc");
            return (bool) ret;
    }
  • AArch64 platform
    static inline bool
    pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr,
                                                                            uint32 *expected, uint32 newval)
    {
            /* FIXME: we can probably use a lower consistency model */
            return __atomic_compare_exchange_n(&ptr->value, expected, newval, false,
                                                                               __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
    }
     
    static inline bool
    pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr,
                                                                            uint32 *expected, uint32 newval)
    {
            bool    ret;
            uint32  current;
            current = __sync_val_compare_and_swap(&ptr->value, *expected, newval);
            ret = current == *expected;
            *expected = current;
            return ret;
    }