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

> Added 32 bit acquire load/cas and release store/add/sub calls.
>
You only have cas_acquire. Don't you see a need for cas_release? I use that
in one lockless design.

I see the beginning of a combinatorial explosion here. Why not just expose
the atomic operations that take the memory ordering as a parameter?

-- Ola


> These are the minimum set of non-relaxed calls that are needed
> for building lock-free algorithms. 64 bit versions can be added
> later.
>
> Signed-off-by: Petri Savolainen <[email protected]>
> ---
>  include/odp/api/atomic.h                    | 80
> ++++++++++++++++++++++++++++-
>  platform/linux-generic/include/odp/atomic.h | 32 ++++++++++++
>  2 files changed, 111 insertions(+), 1 deletion(-)
>
> diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
> index 957d304..cbf241d 100644
> --- a/include/odp/api/atomic.h
> +++ b/include/odp/api/atomic.h
> @@ -21,7 +21,7 @@ extern "C" {
>  /**
>   * @defgroup odp_atomic ODP ATOMIC
>   * @details
> - * <b> Atomic integers </b>
> + * <b> Atomic integers using relaxed memory ordering </b>
>   *
>   * Atomic integer types (odp_atomic_u32_t and odp_atomic_u64_t) can be
> used to
>   * implement e.g. shared counters. If not otherwise documented,
> operations in
> @@ -31,6 +31,18 @@ extern "C" {
>   * before or after the operation), only atomicity of the operation itself
> is
>   * guaranteed.
>   *
> + * <b> Operations with other than relaxed memory ordering </b>
> + *
> + * <b> An operation with RELEASE </b> memory ordering
> (odp_atomic_xxx_rls_xxx())
> + * ensures that other threads loading the same atomic variable with
> ACQUIRE
> + * memory ordering see all stores (from the calling thread) that happened
> before
> + * this releasing store.
> + *
> + * <b> An operation with ACQUIRE </b> memory ordering
> (odp_atomic_xxx_acq_xxx())
> + * ensures that the calling thread sees all stores (done by the releasing
> + * thread) that happened before a RELEASE memory ordered store to the same
> + * atomic variable.
> + *
>   * @{
>   */
>
> @@ -265,6 +277,72 @@ void odp_atomic_dec_u64(odp_atomic_u64_t *atom);
>  int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val,
>                        uint64_t new_val);
>
> +/*
> + * Operations with other than relaxed memory ordering
> + * --------------------------------------------------
> + */
> +
> +/**
> + * Load value of atomic uint32 variable using ACQUIRE memory ordering
> + *
> + * Otherwise identical to odp_atomic_load_u32() but ensures ACQUIRE memory
> + * ordering.
> + *
> + * @param atom    Pointer to atomic variable
> + *
> + * @return Value of the variable
> + */
> +uint32_t odp_atomic_load_acq_u32(odp_atomic_u32_t *atom);
> +
> +/**
> + * Compare and swap atomic uint32 variable using ACQUIRE memory ordering
> + *
> + * Otherwise identical to odp_atomic_cas_u32() but ensures ACQUIRE memory
> + * ordering.
> + *
> + * @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_acq_u32(odp_atomic_u32_t *atom, uint32_t *old_val,
> +                          uint32_t new_val);
> +
> +/**
> + * Store value to atomic uint32 variable using RELEASE memory ordering
> + *
> + * Otherwise identical to odp_atomic_store_u32() but ensures RELEASE
> memory
> + * ordering.
> + *
> + * @param atom    Pointer to atomic variable
> + * @param val     Value to store in the variable
> + */
> +void odp_atomic_store_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
> +
> +/**
> + * Add to atomic uint32 variable using RELEASE memory ordering
> + *
> + * Otherwise identical to odp_atomic_add_u32() but ensures RELEASE memory
> + * ordering.
> + *
> + * @param atom    Pointer to atomic variable
> + * @param val     Value to be added to the variable
> + */
> +void odp_atomic_add_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
> +
> +/**
> + * Subtract from atomic uint32 variable using RELEASE memory ordering
> + *
> + * Otherwise identical to odp_atomic_sub_u32() but ensures RELEASE memory
> + * ordering.
> + *
> + * @param atom    Pointer to atomic variable
> + * @param val     Value to be subtracted from the variable
> + */
> +void odp_atomic_sub_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
> +
>  /**
>   * @}
>   */
> diff --git a/platform/linux-generic/include/odp/atomic.h
> b/platform/linux-generic/include/odp/atomic.h
> index 5a143a5..8f83c04 100644
> --- a/platform/linux-generic/include/odp/atomic.h
> +++ b/platform/linux-generic/include/odp/atomic.h
> @@ -204,6 +204,38 @@ static inline int odp_atomic_cas_u64(odp_atomic_u64_t
> *atom, uint64_t *old_val,
>                                            __ATOMIC_RELAXED);
>  }
>
> +static inline uint32_t odp_atomic_load_acq_u32(odp_atomic_u32_t *atom)
> +{
> +       return __atomic_load_n(&atom->v, __ATOMIC_ACQUIRE);
> +}
> +
> +static inline int odp_atomic_cas_acq_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_ACQUIRE,
> +                                          __ATOMIC_RELAXED);
> +}
> +
> +static inline void odp_atomic_store_rls_u32(odp_atomic_u32_t *atom,
> +                                           uint32_t val)
> +{
> +       __atomic_store_n(&atom->v, val, __ATOMIC_RELEASE);
> +}
> +
> +static inline void odp_atomic_add_rls_u32(odp_atomic_u32_t *atom,
> +                                         uint32_t val)
> +{
> +       (void)__atomic_fetch_add(&atom->v, val, __ATOMIC_RELEASE);
> +}
> +
> +static inline void odp_atomic_sub_rls_u32(odp_atomic_u32_t *atom,
> +                                         uint32_t val)
> +{
> +       (void)__atomic_fetch_sub(&atom->v, val, __ATOMIC_RELEASE);
> +}
> +
>  /**
>   * @}
>   */
> --
> 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