[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