/**
* Copyright (c) NVIDIA CORPORATION & AFFILIATES, 2001-2015. ALL RIGHTS RESERVED.
*
* See file LICENSE for terms.
*/

#ifndef UCS_GENERIC_ATOMIC_H_
#define UCS_GENERIC_ATOMIC_H_


#define UCS_DEFINE_ATOMIC_ADD(wordsize, suffix) \
    static inline void ucs_atomic_add##wordsize(volatile uint##wordsize##_t *ptr, \
                                                uint##wordsize##_t value) { \
        __sync_add_and_fetch(ptr, value); \
    }

#define UCS_DEFINE_ATOMIC_FADD(wordsize, suffix) \
    static inline uint##wordsize##_t ucs_atomic_fadd##wordsize(volatile uint##wordsize##_t *ptr, \
                                                               uint##wordsize##_t value) { \
        return __sync_fetch_and_add(ptr, value); \
    }

#define UCS_DEFINE_ATOMIC_SWAP(wordsize, suffix) \
    static inline uint##wordsize##_t ucs_atomic_swap##wordsize(volatile uint##wordsize##_t *ptr, \
                                                               uint##wordsize##_t value) { \
        uint##wordsize##_t old; \
        do { \
           old = *ptr; \
        } while(old != __sync_val_compare_and_swap(ptr, old, value)); \
        return old; \
    }

#define UCS_DEFINE_ATOMIC_CSWAP(wordsize, suffix) \
    static inline uint##wordsize##_t ucs_atomic_cswap##wordsize(volatile uint##wordsize##_t *ptr, \
                                                                uint##wordsize##_t compare, \
                                                                uint##wordsize##_t swap) { \
        return __sync_val_compare_and_swap(ptr, compare, swap); \
    }

#define UCS_DEFINE_ATOMIC_BOOL_CSWAP(wordsize, suffix) \
    static inline uint##wordsize##_t ucs_atomic_bool_cswap##wordsize(volatile uint##wordsize##_t *ptr, \
                                                                     uint##wordsize##_t compare, \
                                                                     uint##wordsize##_t swap) { \
        return __sync_bool_compare_and_swap(ptr, compare, swap); \
    }

#endif
