diff --git a/CMakeLists.txt b/CMakeLists.txt index 8127e0965..d834eb6d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,7 @@ option(MI_BUILD_TESTS "Build test executables" ON) option(MI_DEBUG_TSAN "Build with thread sanitizer (needs clang)" OFF) option(MI_DEBUG_UBSAN "Build with undefined-behavior sanitizer (needs clang++)" OFF) option(MI_SKIP_COLLECT_ON_EXIT, "Skip collecting memory on program exit" OFF) +option(MI_ATOMIC_FOR_GCC485 "Build with custom stdatomic.h for gcc-4.8.5" OFF) # deprecated options option(MI_CHECK_FULL "Use full internal invariant checking in DEBUG mode (deprecated, use MI_DEBUG_FULL instead)" OFF) @@ -143,6 +144,11 @@ if(MI_SHOW_ERRORS) list(APPEND mi_defines MI_SHOW_ERRORS=1) endif() +if(MI_ATOMIC_FOR_GCC485) + message(STATUS "Enable using cumstom stdatomic.h file for gcc 4.8.5 (MI_ATOMIC_FOR_GCC485=ON)") + list(APPEND mi_defines MI_ATOMIC_FOR_GCC485=1) +endif() + if(MI_DEBUG_TSAN) if(CMAKE_C_COMPILER_ID MATCHES "Clang") message(STATUS "Build with thread sanitizer (MI_DEBUG_TSAN=ON)") diff --git a/include/gcc-4.8.5-atomic.h b/include/gcc-4.8.5-atomic.h new file mode 100644 index 000000000..ba294e7b3 --- /dev/null +++ b/include/gcc-4.8.5-atomic.h @@ -0,0 +1,43 @@ +/** + * @file gcc-4.8.5-atomic.h + * + * @author shadow-yuan (shadow_yuan@qq.com) + * + * @brief because gcc-4.8.5 does not include the file stdatomic.h + * so add this file to pass the compilation + * + */ +#ifndef MI_FOR_GCC_485_ATOMIC_H_ +#define MI_FOR_GCC_485_ATOMIC_H_ + +#define memory_order_relaxed __ATOMIC_RELAXED +#define memory_order_consume __ATOMIC_CONSUME +#define memory_order_acquire __ATOMIC_ACQUIRE +#define memory_order_release __ATOMIC_RELEASE +#define memory_order_acq_rel __ATOMIC_ACQ_REL +#define memory_order_seq_cst __ATOMIC_SEQ_CST + +#define _Atomic(x) x + +#define __has_include(x) (1) + +#define atomic_load_explicit(p, m) __atomic_load_n(p, m) +#define atomic_store_explicit(p, x, m) __atomic_store_n(p, x, m) + +#define atomic_exchange(p, x) __atomic_exchange_n(p, x, memory_order_seq_cst) +#define atomic_exchange_explicit(p, x, m) __atomic_exchange_n(p, x, m) + +#define atomic_compare_exchange_weak_explicit(p, expected, desired, mem_success, mem_fail) \ + __atomic_compare_exchange_n(p, expected, desired, 1, mem_success, mem_fail) + +#define atomic_compare_exchange_strong_explicit(p, expected, desired, mem_success, mem_fail) \ + __atomic_compare_exchange_n(p, expected, desired, 0, mem_success, mem_fail) + +#define atomic_fetch_add_explicit(p, x, m) __atomic_fetch_add(p, x, m) +#define atomic_fetch_sub_explicit(p, x, m) __atomic_fetch_sub(p, x, m) +#define atomic_fetch_and_explicit(p, x, m) __atomic_fetch_and(p, x, m) +#define atomic_fetch_or_explicit(p, x, m) __atomic_fetch_or(p, x, m) + +#define ATOMIC_VAR_INIT(x) (x) + +#endif // MI_FOR_GCC_485_ATOMIC_H_ diff --git a/include/mimalloc-atomic.h b/include/mimalloc-atomic.h index 7ad5da585..1f4ea140e 100644 --- a/include/mimalloc-atomic.h +++ b/include/mimalloc-atomic.h @@ -34,6 +34,11 @@ terms of the MIT license. A copy of the license can be found in the file #define MI_ATOMIC_VAR_INIT(x) x #define mi_atomic(name) mi_atomic_##name #define mi_memory_order(name) mi_memory_order_##name +#elif defined(MI_ATOMIC_FOR_GCC485) +#include +#define mi_atomic(name) atomic_##name +#define mi_memory_order(name) memory_order_##name +#define MI_ATOMIC_VAR_INIT(x) x #else // Use C11 atomics #include diff --git a/test/test-stress.c b/test/test-stress.c index ff5fffeb1..4c6608ce6 100644 --- a/test/test-stress.c +++ b/test/test-stress.c @@ -336,7 +336,11 @@ static void* atomic_exchange_ptr(volatile void** p, void* newval) { return std::atomic_exchange((volatile std::atomic*)p, newval); } #else +#if defined(MI_ATOMIC_FOR_GCC485) +#include +#else #include +#endif static void* atomic_exchange_ptr(volatile void** p, void* newval) { return atomic_exchange((volatile _Atomic(void*)*)p, newval); }