From 559aa84c7468c438c7baa167e9d73b7974d8684c Mon Sep 17 00:00:00 2001 From: Gianfranco Costamagna Date: Tue, 10 Jan 2023 14:20:30 +0100 Subject: [PATCH 1/3] Add CheckAtomic.cmake from cmake-extra-modules package Add check for atomic need (e.g. this fixes the build on riscv64 architecture) --- CMakeLists.txt | 1 + cmake/CheckAtomic.cmake | 95 +++++++++++++++++++++++++++++++++++++++++ src/lib/CMakeLists.txt | 6 +++ 3 files changed, 102 insertions(+) create mode 100644 cmake/CheckAtomic.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 99f0d3f3c..f369fba74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -212,6 +212,7 @@ set(CONFIGURATION_FILES_DIR ${CMAKE_INSTALL_FULL_SYSCONFDIR}) add_definitions(-DCONFIGURATION_FILES_DIR="${CONFIGURATION_FILES_DIR}") add_subdirectory(cmake) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") if (WITH_DLT_NETWORK_TRACE) # Message queue diff --git a/cmake/CheckAtomic.cmake b/cmake/CheckAtomic.cmake new file mode 100644 index 000000000..d154b1177 --- /dev/null +++ b/cmake/CheckAtomic.cmake @@ -0,0 +1,95 @@ +# SPDX-FileCopyrightText: 2003-2018 University of Illinois at Urbana-Champaign. +# +# SPDX-License-Identifier: BSD-3-Clause + +#[=======================================================================[.rst: +CheckAtomic +----------- + +Check if the compiler supports std:atomic out of the box or if libatomic is +needed for atomic support. If it is needed libatomicis added to +``CMAKE_REQUIRED_LIBRARIES``. So after running CheckAtomic you can use +std:atomic. + +Since 5.75.0. +#]=======================================================================] + +include(CheckCXXSourceCompiles) +include(CheckLibraryExists) + +# Sometimes linking against libatomic is required for atomic ops, if +# the platform doesn't support lock-free atomics. + +function(check_working_cxx_atomics varname) + set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11") + check_cxx_source_compiles(" + #include + std::atomic x; + std::atomic y; + std::atomic z; + int main() { + ++z; + ++y; + return ++x; + } + " ${varname}) + set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) +endfunction() + +function(check_working_cxx_atomics64 varname) + set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) + set(CMAKE_REQUIRED_FLAGS "-std=c++11 ${CMAKE_REQUIRED_FLAGS}") + check_cxx_source_compiles(" + #include + #include + std::atomic x (0); + int main() { + uint64_t i = x.load(std::memory_order_relaxed); + return 0; + } + " ${varname}) + set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) +endfunction() + +# Check for (non-64-bit) atomic operations. +if(MSVC) + set(HAVE_CXX_ATOMICS_WITHOUT_LIB True) +elseif(LLVM_COMPILER_IS_GCC_COMPATIBLE) + # First check if atomics work without the library. + check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB) + # If not, check if the library exists, and atomics work with it. + if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB) + check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC) + if(HAVE_LIBATOMIC) + list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") + check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB) + if (NOT HAVE_CXX_ATOMICS_WITH_LIB) + message(FATAL_ERROR "Host compiler must support std::atomic!") + endif() + else() + message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.") + endif() + endif() +endif() + +# Check for 64 bit atomic operations. +if(MSVC) + set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True) +elseif(LLVM_COMPILER_IS_GCC_COMPATIBLE) + # First check if atomics work without the library. + check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB) + # If not, check if the library exists, and atomics work with it. + if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB) + check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64) + if(HAVE_CXX_LIBATOMICS64) + list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") + check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB) + if (NOT HAVE_CXX_ATOMICS64_WITH_LIB) + message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!") + endif() + else() + message(FATAL_ERROR "Host compiler appears to require libatomic for 64-bit operations, but cannot find it.") + endif() + endif() +endif() diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 3293376a1..0f6155053 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -44,6 +44,12 @@ else() message(STATUS "pthread_setname_np API not available on this platform") endif() +# Test for Atomics +include(CheckAtomic) +if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB OR NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB) + target_link_libraries(dlt "atomic") +endif() + target_link_libraries(dlt ${RT_LIBRARY} ${SOCKET_LIBRARY} Threads::Threads) target_include_directories(dlt From 0d18b4f11eeaa434c81cfe81dd6d4b890817bc54 Mon Sep 17 00:00:00 2001 From: Gianfranco Costamagna Date: Wed, 18 Jan 2023 20:17:31 +0100 Subject: [PATCH 2/3] Revert "Add CheckAtomic.cmake from cmake-extra-modules package" This reverts commit 559aa84c7468c438c7baa167e9d73b7974d8684c. --- CMakeLists.txt | 1 - cmake/CheckAtomic.cmake | 95 ----------------------------------------- src/lib/CMakeLists.txt | 6 --- 3 files changed, 102 deletions(-) delete mode 100644 cmake/CheckAtomic.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index f369fba74..99f0d3f3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -212,7 +212,6 @@ set(CONFIGURATION_FILES_DIR ${CMAKE_INSTALL_FULL_SYSCONFDIR}) add_definitions(-DCONFIGURATION_FILES_DIR="${CONFIGURATION_FILES_DIR}") add_subdirectory(cmake) -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") if (WITH_DLT_NETWORK_TRACE) # Message queue diff --git a/cmake/CheckAtomic.cmake b/cmake/CheckAtomic.cmake deleted file mode 100644 index d154b1177..000000000 --- a/cmake/CheckAtomic.cmake +++ /dev/null @@ -1,95 +0,0 @@ -# SPDX-FileCopyrightText: 2003-2018 University of Illinois at Urbana-Champaign. -# -# SPDX-License-Identifier: BSD-3-Clause - -#[=======================================================================[.rst: -CheckAtomic ------------ - -Check if the compiler supports std:atomic out of the box or if libatomic is -needed for atomic support. If it is needed libatomicis added to -``CMAKE_REQUIRED_LIBRARIES``. So after running CheckAtomic you can use -std:atomic. - -Since 5.75.0. -#]=======================================================================] - -include(CheckCXXSourceCompiles) -include(CheckLibraryExists) - -# Sometimes linking against libatomic is required for atomic ops, if -# the platform doesn't support lock-free atomics. - -function(check_working_cxx_atomics varname) - set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11") - check_cxx_source_compiles(" - #include - std::atomic x; - std::atomic y; - std::atomic z; - int main() { - ++z; - ++y; - return ++x; - } - " ${varname}) - set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) -endfunction() - -function(check_working_cxx_atomics64 varname) - set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) - set(CMAKE_REQUIRED_FLAGS "-std=c++11 ${CMAKE_REQUIRED_FLAGS}") - check_cxx_source_compiles(" - #include - #include - std::atomic x (0); - int main() { - uint64_t i = x.load(std::memory_order_relaxed); - return 0; - } - " ${varname}) - set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) -endfunction() - -# Check for (non-64-bit) atomic operations. -if(MSVC) - set(HAVE_CXX_ATOMICS_WITHOUT_LIB True) -elseif(LLVM_COMPILER_IS_GCC_COMPATIBLE) - # First check if atomics work without the library. - check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB) - # If not, check if the library exists, and atomics work with it. - if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB) - check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC) - if(HAVE_LIBATOMIC) - list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") - check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB) - if (NOT HAVE_CXX_ATOMICS_WITH_LIB) - message(FATAL_ERROR "Host compiler must support std::atomic!") - endif() - else() - message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.") - endif() - endif() -endif() - -# Check for 64 bit atomic operations. -if(MSVC) - set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True) -elseif(LLVM_COMPILER_IS_GCC_COMPATIBLE) - # First check if atomics work without the library. - check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB) - # If not, check if the library exists, and atomics work with it. - if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB) - check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64) - if(HAVE_CXX_LIBATOMICS64) - list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") - check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB) - if (NOT HAVE_CXX_ATOMICS64_WITH_LIB) - message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!") - endif() - else() - message(FATAL_ERROR "Host compiler appears to require libatomic for 64-bit operations, but cannot find it.") - endif() - endif() -endif() diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 0f6155053..3293376a1 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -44,12 +44,6 @@ else() message(STATUS "pthread_setname_np API not available on this platform") endif() -# Test for Atomics -include(CheckAtomic) -if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB OR NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB) - target_link_libraries(dlt "atomic") -endif() - target_link_libraries(dlt ${RT_LIBRARY} ${SOCKET_LIBRARY} Threads::Threads) target_include_directories(dlt From 8d109333dafbd6de76935c2ff4cc412d36e73761 Mon Sep 17 00:00:00 2001 From: Gianfranco Costamagna Date: Wed, 18 Jan 2023 20:19:05 +0100 Subject: [PATCH 3/3] Change atomic bool to atomic int, this way riscv64 builds fine without needing of external latomic, because gcc is not able to optimize natively the code. --- src/lib/dlt_user.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/dlt_user.c b/src/lib/dlt_user.c index 0085593c8..8f1fc8d9d 100644 --- a/src/lib/dlt_user.c +++ b/src/lib/dlt_user.c @@ -91,7 +91,7 @@ #endif /* DLT_FATAL_LOG_RESET_ENABLE */ static DltUser dlt_user; -static atomic_bool dlt_user_initialised = false; +static atomic_int dlt_user_initialised = false; static int dlt_user_freeing = 0; static bool dlt_user_file_reach_max = false; @@ -451,7 +451,7 @@ DltReturnValue dlt_init(void) pass fully. The other one will immediately return, because when it executes the atomic function 'dlt_user_initialised' will be for sure already set to true. */ - bool expected = false; + int expected = false; if (!(atomic_compare_exchange_strong(&dlt_user_initialised, &expected, true))) return DLT_RETURN_OK; @@ -563,7 +563,7 @@ DltReturnValue dlt_init_file(const char *name) pass fully. The other one will immediately return, because when it executes the atomic function 'dlt_user_initialised' will be for sure already set to true. */ - bool expected = false; + int expected = false; if (!(atomic_compare_exchange_strong(&dlt_user_initialised, &expected, true))) return DLT_RETURN_OK;