[Mesa-dev] [PATCH v2 2/8] util/u_atomic: add p_atomic_xchg

Marek Olšák maraeo at gmail.com
Fri Nov 3 22:58:44 UTC 2017


Reviewed-by: Marek Olšák <marek.olsak at amd.com>

Marek

On Fri, Nov 3, 2017 at 9:09 PM, Nicolai Hähnle <nhaehnle at gmail.com> wrote:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
>
> The closest to it in the old-style gcc builtins is __sync_lock_test_and_set,
> however, that is only guaranteed to work with values 0 and 1 and only
> provides an acquire barrier. I also don't know about other OSes, so we
> provide a simple & stupid emulation via p_atomic_cmpxchg.
> ---
>  src/util/u_atomic.h | 32 +++++++++++++++++++++++++++++++-
>  1 file changed, 31 insertions(+), 1 deletion(-)
>
> diff --git a/src/util/u_atomic.h b/src/util/u_atomic.h
> index 2a5bbae295b..c6d4bde3439 100644
> --- a/src/util/u_atomic.h
> +++ b/src/util/u_atomic.h
> @@ -5,20 +5,21 @@
>   * No copyright claimed on this file.
>   *
>   */
>
>  #include "no_extern_c.h"
>
>  #ifndef U_ATOMIC_H
>  #define U_ATOMIC_H
>
>  #include <stdbool.h>
> +#include <stdint.h>
>
>  /* Favor OS-provided implementations.
>   *
>   * Where no OS-provided implementation is available, fall back to
>   * locally coded assembly, compiler intrinsic or ultimately a
>   * mutex-based implementation.
>   */
>  #if defined(__sun)
>  #define PIPE_ATOMIC_OS_SOLARIS
>  #elif defined(_MSC_VER)
> @@ -40,20 +41,22 @@
>
>  /* The builtins with explicit memory model are available since GCC 4.7. */
>  #define p_atomic_set(_v, _i) __atomic_store_n((_v), (_i), __ATOMIC_RELEASE)
>  #define p_atomic_read(_v) __atomic_load_n((_v), __ATOMIC_ACQUIRE)
>  #define p_atomic_dec_zero(v) (__atomic_sub_fetch((v), 1, __ATOMIC_ACQ_REL) == 0)
>  #define p_atomic_inc(v) (void) __atomic_add_fetch((v), 1, __ATOMIC_ACQ_REL)
>  #define p_atomic_dec(v) (void) __atomic_sub_fetch((v), 1, __ATOMIC_ACQ_REL)
>  #define p_atomic_add(v, i) (void) __atomic_add_fetch((v), (i), __ATOMIC_ACQ_REL)
>  #define p_atomic_inc_return(v) __atomic_add_fetch((v), 1, __ATOMIC_ACQ_REL)
>  #define p_atomic_dec_return(v) __atomic_sub_fetch((v), 1, __ATOMIC_ACQ_REL)
> +#define p_atomic_xchg(v, i) __atomic_exchange_n((v), (i), __ATOMIC_ACQ_REL)
> +#define PIPE_NATIVE_ATOMIC_XCHG
>
>  #else
>
>  #define p_atomic_set(_v, _i) (*(_v) = (_i))
>  #define p_atomic_read(_v) (*(_v))
>  #define p_atomic_dec_zero(v) (__sync_sub_and_fetch((v), 1) == 0)
>  #define p_atomic_inc(v) (void) __sync_add_and_fetch((v), 1)
>  #define p_atomic_dec(v) (void) __sync_sub_and_fetch((v), 1)
>  #define p_atomic_add(v, i) (void) __sync_add_and_fetch((v), (i))
>  #define p_atomic_inc_return(v) __sync_add_and_fetch((v), 1)
> @@ -213,13 +216,40 @@
>     sizeof(*v) == sizeof(uint32_t) ? atomic_cas_32((uint32_t *)(v), (uint32_t)(old), (uint32_t)(_new)) : \
>     sizeof(*v) == sizeof(uint64_t) ? atomic_cas_64((uint64_t *)(v), (uint64_t)(old), (uint64_t)(_new)) : \
>                                      (assert(!"should not get here"), 0))
>
>  #endif
>
>  #ifndef PIPE_ATOMIC
>  #error "No pipe_atomic implementation selected"
>  #endif
>
> -
> +#ifndef PIPE_NATIVE_ATOMIC_XCHG
> +static inline uint32_t p_atomic_xchg_32(uint32_t *v, uint32_t i)
> +{
> +   uint32_t actual = p_atomic_read(v);
> +   uint32_t expected;
> +   do {
> +      expected = actual;
> +      actual = p_atomic_cmpxchg(v, expected, i);
> +   } while (expected != actual);
> +   return actual;
> +}
> +
> +static inline uint64_t p_atomic_xchg_64(uint64_t *v, uint64_t i)
> +{
> +   uint64_t actual = p_atomic_read(v);
> +   uint64_t expected;
> +   do {
> +      expected = actual;
> +      actual = p_atomic_cmpxchg(v, expected, i);
> +   } while (expected != actual);
> +   return actual;
> +}
> +
> +#define p_atomic_xchg(v, i) ((__typeof(*(v))) \
> +   sizeof(*(v)) == sizeof(uint32_t) ? p_atomic_xchg_32((uint32_t *)(v), (uint32_t)(i)) : \
> +   sizeof(*(v)) == sizeof(uint64_t) ? p_atomic_xchg_64((uint64_t *)(v), (uint64_t)(i)) : \
> +                                      (assert(!"should not get here"), 0))
> +#endif
>
>  #endif /* U_ATOMIC_H */
> --
> 2.11.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list