On 15 October 2015 at 10:45, Petri Savolainen <[email protected]>
wrote:

> Added cas operations for 32 and 64 bit atomic variables. These
> use relaxed memory order (as all other operations).
>
Do you have actual use cases for CAS where *only* relaxed memory order is
required? Or you need CAS with acquire ordering per the other patch? But
you don't need CAS with release ordering?

I would rather see a generic CAS function with the memory order as a
separate parameter. We are into lock-less territory now, not just using
atomics for simple counters/statistics where we don't have to worry about
memory ordering.


>
> Signed-off-by: Petri Savolainen <[email protected]>
> ---
>  include/odp/api/atomic.h                    | 37
> +++++++++++++++++++++++++++++
>  platform/linux-generic/include/odp/atomic.h | 18 ++++++++++++++
>  2 files changed, 55 insertions(+)
>
> diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
> index 97e8639..957d304 100644
> --- a/include/odp/api/atomic.h
> +++ b/include/odp/api/atomic.h
> @@ -136,6 +136,25 @@ uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t
> *atom);
>  void odp_atomic_dec_u32(odp_atomic_u32_t *atom);
>
>  /**
> + * Compare and swap atomic uint32 variable
> + *
> + * Compares value of atomic variable to the value pointed by 'old_val'.
> + * If values are equal, the operation writes 'new_val' into the atomic
> variable
> + * and returns success. If they are not equal, the operation writes
> current
> + * value of atomic variable into 'old_val' and returns failure.
> + *
> + * @param         atom      Pointer to atomic variable
> + * @param[in,out] old_val   Pointer to the old value of the atomic
> variable.
> + *                          Operation updates this value on failure.
> + * @param         new_val   New value to be written into the atomic
> variable
> + *
> + * @return 0 on failure, !0 on success
> + *
> + */
> +int odp_atomic_cas_u32(odp_atomic_u32_t *atom, uint32_t *old_val,
> +                      uint32_t new_val);
> +
> +/**
>   * Initialize atomic uint64 variable
>   *
>   * @param atom    Pointer to atomic variable
> @@ -229,6 +248,24 @@ uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t
> *atom);
>  void odp_atomic_dec_u64(odp_atomic_u64_t *atom);
>
>  /**
> + * Compare and swap atomic uint64 variable
> + *
> + * Compares value of atomic variable to the value pointed by 'old_val'.
> + * If values are equal, the operation writes 'new_val' into the atomic
> variable
> + * and returns success. If they are not equal, the operation writes
> current
> + * value of atomic variable into 'old_val' and returns failure.
> + *
> + * @param         atom      Pointer to atomic variable
> + * @param[in,out] old_val   Pointer to the old value of the atomic
> variable.
> + *                          Operation updates this value on failure.
> + * @param         new_val   New value to be written into the atomic
> variable
> + *
> + * @return 0 on failure, !0 on success
> + */
> +int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val,
> +                      uint64_t new_val);
> +
> +/**
>   * @}
>   */
>
> diff --git a/platform/linux-generic/include/odp/atomic.h
> b/platform/linux-generic/include/odp/atomic.h
> index deb4039..5a143a5 100644
> --- a/platform/linux-generic/include/odp/atomic.h
> +++ b/platform/linux-generic/include/odp/atomic.h
> @@ -85,6 +85,15 @@ static inline void odp_atomic_dec_u32(odp_atomic_u32_t
> *atom)
>         (void)__atomic_fetch_sub(&atom->v, 1, __ATOMIC_RELAXED);
>  }
>
> +static inline int odp_atomic_cas_u32(odp_atomic_u32_t *atom, uint32_t
> *old_val,
> +                                    uint32_t new_val)
> +{
> +       return __atomic_compare_exchange_n(&atom->v, old_val, new_val,
> +                                          0 /* strong */,
> +                                          __ATOMIC_RELAXED,
> +                                          __ATOMIC_RELAXED);
> +}
> +
>  static inline void odp_atomic_init_u64(odp_atomic_u64_t *atom, uint64_t
> val)
>  {
>         atom->v = val;
> @@ -186,6 +195,15 @@ static inline void
> odp_atomic_dec_u64(odp_atomic_u64_t *atom)
>  #endif
>  }
>
> +static inline int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t
> *old_val,
> +                                    uint64_t new_val)
> +{
> +       return __atomic_compare_exchange_n(&atom->v, old_val, new_val,
> +                                          0 /* strong */,
> +                                          __ATOMIC_RELAXED,
> +                                          __ATOMIC_RELAXED);
> +}
> +
>  /**
>   * @}
>   */
> --
> 2.6.0
>
> _______________________________________________
> lng-odp mailing list
> [email protected]
> https://lists.linaro.org/mailman/listinfo/lng-odp
>
_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to