bin/contrib/memaslap: attempt to fix atomics detection
authorMichael Wallner <mike@php.net>
Tue, 24 Nov 2020 14:28:40 +0000 (15:28 +0100)
committerMichael Wallner <mike@php.net>
Tue, 24 Nov 2020 14:28:40 +0000 (15:28 +0100)
CMake/CheckAtomics.cmake [new file with mode: 0644]
CMake/CheckStdatomic.cmake [deleted file]
CMake/_Include.cmake
CMakeConfig.txt
src/bin/contrib/CMakeLists.txt
src/bin/contrib/memaslap.c
src/bin/contrib/memaslap/ms_atomic.h
src/mem_config.h.in

diff --git a/CMake/CheckAtomics.cmake b/CMake/CheckAtomics.cmake
new file mode 100644 (file)
index 0000000..9d12276
--- /dev/null
@@ -0,0 +1,58 @@
+include(CheckCSourceRuns)
+include(CheckCXXSourceRuns)
+
+# sets HAVE_ATOMICS, checks for :
+# - C++11 std::atomic:  HAVE_CXX_STDATOMIC
+# - C11 stdatomic:      HAVE_C_STDATOMIC
+# - builtin __atomic:   HAVE_BUILTIN_ATOMIC
+# - builtin __sync:     HAVE_BUILTIN_SYNC
+# - atomic_add_nv:      HAVE_ATOMIC_ADD_NV
+function(check_atomics)
+    check_cxx_source_runs("
+            #include <atomic>
+            int main() {
+                std::atomic<int> i(0);
+                return atomic_load(&i);
+            }"
+            HAVE_CXX_STDATOMIC)
+    check_c_source_runs("
+            #include <stdatomic.h>
+            int main() {
+                atomic_int i;
+                atomic_init(&i, 0);
+                return atomic_load(&i);
+            }"
+            HAVE_C_STDATOMIC)
+    foreach(BUILTIN_ATOMIC_PREFIX IN ITEMS _ __c11)
+        check_c_source_runs("
+                int main() {
+                    long l = 0;
+                    return ${BUILTIN_ATOMIC_PREFIX}_atomic_add_fetch(&l,1,__ATOMIC_RELAXED);
+                }"
+                HAVE_BUILTIN_ATOMIC${BUILTIN_ATOMIC_PREFIX})
+        if (HAVE_BUILTIN_ATOMIC${BUILTIN_ATOMIC_PREFIX})
+            set(HAVE_BUILTIN_ATOMIC 1)
+            break()
+        endif()
+    endforeach()
+    check_c_source_runs("
+            int main() {
+                long l = 0;
+                return __sync_add_and_fetch(&l,1);
+            }"
+            HAVE_BUILTIN_SYNC)
+    check_c_source_runs("
+            #include <atomic.h>
+            int main() {
+                volatile uint_t i = 0;
+                return atomic_add_int_nv(&i, 1);
+            }"
+            HAVE_ATOMIC_ADD_NV)
+    if (        HAVE_CXX_STDATOMIC
+            OR  HAVE_C_STDATOMIC
+            OR  HAVE_BUILTIN_ATOMIC
+            OR  HAVE_BUILTIN_SYNC
+            OR  HAVE_ATOMIC_ADD_NV)
+        set(HAVE_ATOMICS 1 PARENT_SCOPE)
+    endif()
+endfunction()
diff --git a/CMake/CheckStdatomic.cmake b/CMake/CheckStdatomic.cmake
deleted file mode 100644 (file)
index cd9953b..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-include(CheckCSourceRuns)
-include(CheckCXXSourceRuns)
-
-# check for C11 stdatomic and C++11 std::atomic, set HAVE_C_STDATOMIC and/or HAVE_CXX_STDATOMIC
-function(check_stdatomic)
-    check_cxx_source_runs(
-            "#include <atomic>
-            int main() {
-                std::atomic<int> i(0);
-                return atomic_fetch_add(&i,1);
-            }"
-            HAVE_CXX_STDATOMIC)
-    check_c_source_runs(
-            "#include <stdatomic.h>
-            int main() {
-                atomic_int i;
-                atomic_init(&i, 0);
-                return atomic_fetch_add(&i,1);
-            }"
-            HAVE_C_STDATOMIC)
-endfunction(    )
index 67917c8e10b6720c83ae4bf5586133fbeb7fd013..b4f2dbd182db04d672b17c2fbad9094ed5576755 100644 (file)
@@ -25,7 +25,7 @@ include(CheckDependency)
 include(CheckHeader)
 include(CheckCompiles)
 include(CheckType)
-include(CheckStdatomic)
+include(CheckAtomics)
 include(TestBigEndian)
 include(CheckByteswap)
 
@@ -36,9 +36,8 @@ check_debug()
 
 ## memaslap
 if(ENABLE_MEMASLAP)
-    check_stdatomic()
+    check_atomics()
     check_dependency(LIBEVENT event event.h)
-    check_dependency(LIBMATH m math.h)
     check_decl(getline stdio.h)
     if(HAVE_LIBEVENT AND HAVE_C_STDATOMIC)
         set(HAVE_MEMASLAP 1)
@@ -140,3 +139,4 @@ check_type(in_port_t netinet/in.h)
 
 check_header(cstdint)
 check_header(cinttypes)
+check_header(inttypes.h)
index 7f70b70b03f0812161ef7c4bc1b5fe718f2395dd..50a2be47b0f0751f3cf17a812a3fadc94ae6d1c8 100644 (file)
@@ -85,7 +85,6 @@ endif()
 
 set(HAVE_VISIBILITY 1)
 set(HAVE_SHARED_ENABLED 1)
-set(HAVE_GCC_BUILTIN_ATOMIC 1)
 
 # modules
 
index 40f0a2f068a6fb4b2dfe59969444dffe1b6e2c08..adc7af8a5a852c8cdb09c7941e268a38c9fe50b7 100644 (file)
@@ -9,9 +9,12 @@ if(HAVE_MEMASLAP)
     target_include_directories(memaslap PRIVATE
             memaslap
             ${CMAKE_SOURCE_DIR}/include
+            ${CMAKE_BINARY_DIR}/include
             ${CMAKE_SOURCE_DIR}/src
+            ${CMAKE_BINARY_DIR}/src
             ${CMAKE_BINARY_DIR})
-    target_link_libraries(memaslap PRIVATE libmemcached Threads::Threads ${LIBEVENT} ${LIBMATH})
+    target_link_libraries(memaslap PUBLIC libmemcached Threads::Threads ${LIBEVENT} m)
+    set_property(TARGET memaslap PROPERTY C_STANDARD 11)
     if(CMAKE_INSTALL_RPATH)
         set_target_properties(${CLIENT} PROPERTIES
                 INSTALL_RPATH ${CMAKE_INSTALL_RPATH}/../${CMAKE_INSTALL_LIBDIR})
index 1e99ff7d90c7ba317fe083f1738b0ecd0b9ba11f..d7573eb56a1b7dcd0a1d52a117d56b77a73a2a9d 100644 (file)
@@ -29,6 +29,7 @@
 #  include <time.h>
 #endif
 
+#include "ms_atomic.h"
 #include "ms_sigsegv.h"
 #include "ms_setting.h"
 #include "ms_thread.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 */
index bfc0aa8941795beedfff0ebd03fc4fec0646acf4..d0b3a3e6a513988c4cae3ddbe0bdee4360755631 100644 (file)
 
 #cmakedefine WORDS_BIGENDIAN 1
 
+#cmakedefine HAVE_ATOMIC_ADD_NV 1
+#cmakedefine HAVE_BUILTIN_SYNC 1
+#cmakedefine HAVE_BUILTIN_ATOMIC 1
+#cmakedefine BUILTIN_ATOMIC_PREFIX
 #cmakedefine HAVE_C_STDATOMIC 1
 #cmakedefine HAVE_CXX_STDATOMIC 1
+#cmakedefine HAVE_ATOMICS 1
 
 #cmakedefine HAVE_ABI____CXA_DEMANGLE 1
 #cmakedefine HAVE_BACKTRACE 1
 #cmakedefine HAVE_WINSOCK2_H 1
 #cmakedefine HAVE_WS2TCPIP_H 1
 
+#cmakedefine HAVE_INTTYPES_H 1
 #cmakedefine HAVE_CINTTYPES 1
 #cmakedefine HAVE_CSTDINT 1
-#if defined(__cplusplus)
+#if defined __cplusplus
 #  if defined HAVE_CINTTYPES
 #    include <cinttypes>
 #  elif defined HAVE_CSTDINT
 #    include <cstdint>
 #  endif
-#else
+#elif defined HAVE_INTTYPES_H
 #  include <inttypes.h>
 #endif