bin/contrib/memaslap: attempt to fix atomics detection
[m6w6/libmemcached] / src / bin / contrib / memaslap / ms_atomic.h
index 3cb699194702a204b0b13a06a2349edb1658e708..f50c629bbf8c1c611002b1ee0ef023d2d1e934c2 100644 (file)
 #ifndef CLIENTS_MS_ATOMIC_H
 #define CLIENTS_MS_ATOMIC_H
 
-#if HAVE_C_STDATOMIC
-#  define ATOMIC _Atomic
-#else
-#  define ATOMIC volatile
-#endif
+#include "mem_config.h"
 
-#if defined(__SUNPRO_C)
+#if defined(__SUNPRO_C) || defined(HAVE_ATOMIC_ADD_NV)
+#  define ATOMIC volatile
 #  define _KERNEL
 #  include <atomic.h>
 #  if SIZEOF_SIZE_T == 8
-#    define atomic_add_size(X, Y)    atomic_add_64((X), (Y))
-#    define atomic_add_size_nv(X, Y) atomic_add_64((X), (Y))
-#    define atomic_dec_size(X, Y)    atomic_add_64((X), (Y))
-#    define atomic_dec_size_nv(X, Y) atomic_add_64((X), (Y))
+#    define atomic_add_size(X, Y) atomic_add_64((X), (Y))
 #  else
-#    define atomic_add_size(X, Y)    atomic_add_32((X), (Y))
-#    define atomic_add_size_nv(X, Y) atomic_add_32((X), (Y))
-#    define atomic_dec_size(X, Y)    atomic_add_32((X), (Y))
-#    define atomic_dec_size_nv(X, Y) atomic_add_32((X), (Y))
+#    define atomic_add_size(X, Y) atomic_add_32((X), (Y))
 #  endif
 #  undef _KERNEL
-#elif HAVE_GCC_ATOMIC_BUILTINS
-#  define atomic_add_8(X, Y)       __sync_fetch_and_add((X), (Y))
-#  define atomic_add_16(X, Y)      __sync_fetch_and_add((X), (Y))
-#  define atomic_add_32(X, Y)      __sync_fetch_and_add((X), (Y))
-#  define atomic_add_size(X, Y)    __sync_fetch_and_add((X), (Y))
-#  define atomic_dec_8(X)          __sync_fetch_and_sub((X), 1)
-#  define atomic_dec_16(X)         __sync_fetch_and_sub((X), 1)
-#  define atomic_dec_32(X)         __sync_fetch_and_sub((X), 1)
-#  define atomic_dec_size(X)       __sync_fetch_and_sub((X), 1)
-/* The same as above, but these return the new value instead of void */
-#  define atomic_add_8_nv(X, Y)    __sync_fetch_and_add((X), (Y))
-#  define atomic_add_16_nv(X, Y)   __sync_fetch_and_add((X), (Y))
-#  define atomic_add_32_nv(X, Y)   __sync_fetch_and_add((X), (Y))
-#  define atomic_add_size_nv(X, Y) __sync_fetch_and_add((X), (Y))
-#  define atomic_dec_8_nv(X)       __sync_fetch_and_sub((X), 1)
-#  define atomic_dec_16_nv(X)      __sync_fetch_and_sub((X), 1)
-#  define atomic_dec_32_nv(X)      __sync_fetch_and_sub((X), 1)
-#  define atomic_dec_size_nv(X)    __sync_fetch_and_sub((X), 1)
+
 #elif HAVE_C_STDATOMIC
+#  define ATOMIC _Atomic
 #  include <stdatomic.h>
-#  define atomic_add_8(X, Y)    atomic_fetch_add(X, Y)
-#  define atomic_add_16(X, Y)   atomic_fetch_add(X, Y)
-#  define atomic_add_32(X, Y)   atomic_fetch_add(X, Y)
-#  define atomic_add_size(X, Y) atomic_fetch_add(X, Y)
-#  define atomic_dec_8(X)       atomic_fetch_sub(X, 1)
-#  define atomic_dec_16(X)      atomic_fetch_sub(X, 1)
-#  define atomic_dec_32(X)      atomic_fetch_sub(X, 1)
-#  define atomic_dec_size(X)    atomic_fetch_sub(X, 1)
-/* The same as above, but these return the new value instead of void */
-#  define ATOMIC_ADD_FETCH_DECL(T) \
-    static inline T atomic_add_fetch_##T(ATOMIC T *ptr, T add) { \
-      T des, cur = atomic_load(ptr); \
-      do { \
-        des = cur + add; \
-      } while (!atomic_compare_exchange_weak(ptr, &cur, des)); \
-      return des; \
-    }
-#  define ATOMIC_SUB_FETCH_DECL(T) \
-    T atomic_sub_fetch_##T(ATOMIC T *ptr) { \
-      T des, cur = atomic_load(ptr); \
-      do { \
-        des = cur - 1; \
-      } while (!atomic_compare_exchange_weak(ptr, &cur, des)); \
-      return des; \
-    }
-ATOMIC_ADD_FETCH_DECL(uint8_t)
-#  define atomic_add_8_nv(X, Y)    atomic_add_fetch_uint8_t(X, Y)
-ATOMIC_ADD_FETCH_DECL(uint16_t)
-#  define atomic_add_16_nv(X, Y)   atomic_add_fetch_uint16_t(X, Y)
-ATOMIC_ADD_FETCH_DECL(uint32_t)
-#  define atomic_add_32_nv(X, Y)   atomic_add_fetch_uint32_t(X, Y)
-ATOMIC_ADD_FETCH_DECL(size_t)
-#  define atomic_add_size_nv(X, Y) atomic_add_fetch_size_t(X, Y)
-#  define atomic_dec_8_nv(X)       atomic_sub_fetch<uint8_t>(X, Y)
-#  define atomic_dec_16_nv(X)      atomic_sub_fetch<uint16_t>(X, Y)
-#  define atomic_dec_32_nv(X)      atomic_sub_fetch<uint32_t>(X, Y)
-#  define atomic_dec_size_nv(X)    atomic_sub_fetch<size_t>(X, Y)
+#  define atomic_dec_32(X)        atomic_fetch_sub(X,1)
+#  define atomic_add_32           atomic_fetch_add
+#  define atomic_add_32_nv(X,Y)  (atomic_fetch_add(X,Y)+(Y))
+#  define atomic_add_size         atomic_fetch_add
+
+#elif HAVE_BUILTIN_ATOMIC
+#  define ATOMIC
+#  define atomic_dec_32(X)  BUILTIN_ATOMIC_PREFIX ## _atomic_fetch_sub(X,1)
+#  define atomic_add_32     BUILTIN_ATOMIC_PREFIX ## _atomic_fetch_add
+#  define atomic_add_32_nv  BUILTIN_ATOMIC_PREFIX ## _atomic_add_fetch(X,Y)
+#  define atomic_add_size   BUILTIN_ATOMIC_PREFIX ## _atomic_fetch_add
+
+#elif HAVE_BUILTIN_SYNC
+#  define ATOMIC
+#  define atomic_dec_32(X)  __sync_fetch_and_sub((X), 1)
+#  define atomic_add_32     __sync_fetch_and_add
+#  define atomic_add_32_nv  __sync_add_and_fetch
+#  define atomic_add_size   __sync_fetch_and_add
+
 #else
 #  warning "Atomic operators not found so memslap will not work correctly"
-#  define atomic_add_8(X, Y)       0
-#  define atomic_add_16(X, Y)      0
-#  define atomic_add_32(X, Y)      0
-#  define atomic_add_size(X, Y)    0
-#  define atomic_dec_8(X)          0
-#  define atomic_dec_16(X)         0
-#  define atomic_dec_32(X)         0
-#  define atomic_dec_size(X)       0
-/* The same as above, but these return the new value instead of void */
-#  define atomic_add_8_nv(X, Y)    0
-#  define atomic_add_16_nv(X, Y)   0
-#  define atomic_add_32_nv(X, Y)   0
-#  define atomic_add_size_nv(X, Y) 0
-#  define atomic_dec_8_nv(X)       0
-#  define atomic_dec_16_nv(X)      0
-#  define atomic_dec_32_nv(X)      0
-#  define atomic_dec_size_nv(X)    0
-#endif /* defined(__SUNPRO_C) */
+#  define ATOMIC
+#  define atomic_dec_32(X)    (--(*(X)))
+#  define atomic_add_32(X,Y)  ((*(X))+=(Y))
+#  define atomic_add_32_nv    atomic_add_32
+#  define atomic_add_size     atomic_add_32
+
+#endif
 
 #endif /* CLIENTS_MS_ATOMIC_H */