From ec535cafc2f8b32dbef9084a5df8b70ea60733bb Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 24 Nov 2020 15:28:40 +0100 Subject: [PATCH] bin/contrib/memaslap: attempt to fix atomics detection --- CMake/CheckAtomics.cmake | 58 +++++++++++++ CMake/CheckStdatomic.cmake | 21 ----- CMake/_Include.cmake | 6 +- CMakeConfig.txt | 1 - src/bin/contrib/CMakeLists.txt | 5 +- src/bin/contrib/memaslap.c | 1 + src/bin/contrib/memaslap/ms_atomic.h | 120 ++++++++------------------- src/mem_config.h.in | 10 ++- 8 files changed, 107 insertions(+), 115 deletions(-) create mode 100644 CMake/CheckAtomics.cmake delete mode 100644 CMake/CheckStdatomic.cmake diff --git a/CMake/CheckAtomics.cmake b/CMake/CheckAtomics.cmake new file mode 100644 index 00000000..9d12276d --- /dev/null +++ b/CMake/CheckAtomics.cmake @@ -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 + int main() { + std::atomic i(0); + return atomic_load(&i); + }" + HAVE_CXX_STDATOMIC) + check_c_source_runs(" + #include + 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 + 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 index cd9953bf..00000000 --- a/CMake/CheckStdatomic.cmake +++ /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 - int main() { - std::atomic i(0); - return atomic_fetch_add(&i,1); - }" - HAVE_CXX_STDATOMIC) - check_c_source_runs( - "#include - int main() { - atomic_int i; - atomic_init(&i, 0); - return atomic_fetch_add(&i,1); - }" - HAVE_C_STDATOMIC) -endfunction( ) diff --git a/CMake/_Include.cmake b/CMake/_Include.cmake index 67917c8e..b4f2dbd1 100644 --- a/CMake/_Include.cmake +++ b/CMake/_Include.cmake @@ -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) diff --git a/CMakeConfig.txt b/CMakeConfig.txt index 7f70b70b..50a2be47 100644 --- a/CMakeConfig.txt +++ b/CMakeConfig.txt @@ -85,7 +85,6 @@ endif() set(HAVE_VISIBILITY 1) set(HAVE_SHARED_ENABLED 1) -set(HAVE_GCC_BUILTIN_ATOMIC 1) # modules diff --git a/src/bin/contrib/CMakeLists.txt b/src/bin/contrib/CMakeLists.txt index 40f0a2f0..adc7af8a 100644 --- a/src/bin/contrib/CMakeLists.txt +++ b/src/bin/contrib/CMakeLists.txt @@ -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}) diff --git a/src/bin/contrib/memaslap.c b/src/bin/contrib/memaslap.c index 1e99ff7d..d7573eb5 100644 --- a/src/bin/contrib/memaslap.c +++ b/src/bin/contrib/memaslap.c @@ -29,6 +29,7 @@ # include #endif +#include "ms_atomic.h" #include "ms_sigsegv.h" #include "ms_setting.h" #include "ms_thread.h" diff --git a/src/bin/contrib/memaslap/ms_atomic.h b/src/bin/contrib/memaslap/ms_atomic.h index 3cb69919..f50c629b 100644 --- a/src/bin/contrib/memaslap/ms_atomic.h +++ b/src/bin/contrib/memaslap/ms_atomic.h @@ -16,103 +16,49 @@ #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 # 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 -# 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(X, Y) -# define atomic_dec_16_nv(X) atomic_sub_fetch(X, Y) -# define atomic_dec_32_nv(X) atomic_sub_fetch(X, Y) -# define atomic_dec_size_nv(X) atomic_sub_fetch(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 */ diff --git a/src/mem_config.h.in b/src/mem_config.h.in index bfc0aa89..d0b3a3e6 100644 --- a/src/mem_config.h.in +++ b/src/mem_config.h.in @@ -22,8 +22,13 @@ #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 @@ -74,15 +79,16 @@ #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 # elif defined HAVE_CSTDINT # include # endif -#else +#elif defined HAVE_INTTYPES_H # include #endif -- 2.30.2