diff --git a/CMakeLists.txt b/CMakeLists.txt index 16494520df1e1d65b4bac5ac8996f334a48f8662..3fe28afe5c90ee35241e82ff92ca1a49ab49d137 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,6 +89,9 @@ project(Gaudi VERSION 35.0 # Add the "Developer" build type include(cmake/DeveloperBuildType.cmake) +# Set up the GAUDI_ATOMIC_LIBS variable +include(cmake/GaudiAtomicLibs.cmake) + # Import Gaudi functions (gaudi_*) ==> for documentation look in the file include(cmake/GaudiToolbox.cmake) diff --git a/GaudiCommonSvc/CMakeLists.txt b/GaudiCommonSvc/CMakeLists.txt index 06bb97515be6af912073621001946682d3e11976..81988f48472e09156ddb885a150c94af2c4dd42c 100644 --- a/GaudiCommonSvc/CMakeLists.txt +++ b/GaudiCommonSvc/CMakeLists.txt @@ -62,7 +62,8 @@ gaudi_add_module(GaudiCommonSvc Boost::system Boost::filesystem ROOT::Hist - ROOT::RIO) + ROOT::RIO + ${GAUDI_ATOMIC_LIBS}) if(GAUDI_USE_AIDA) target_sources(GaudiCommonSvc PRIVATE src/HistogramSvc/Factory.cpp src/HistogramPersistencySvc/HistogramPersistencySvc.cpp) diff --git a/GaudiConfiguration/CMakeLists.txt b/GaudiConfiguration/CMakeLists.txt index 2faef061b3e8846bca3bb5c64840ee32c09871ff..bafb90753cf6ea0a9ef6b810aa7303e28f68f5df 100644 --- a/GaudiConfiguration/CMakeLists.txt +++ b/GaudiConfiguration/CMakeLists.txt @@ -13,16 +13,18 @@ # Install python modules gaudi_install(PYTHON) -# FIXME: gaudi_add_test(nosetests) is not configurable enough, so I copied a bit of it -_import_nosetests() -add_test(NAME GaudiConfiguration.nose - COMMAND run $<TARGET_FILE:nosetests> -v --with-doctest --with-coverage --cover-package=GaudiConfig2 - ${CMAKE_CURRENT_SOURCE_DIR}/tests/nose) +if(BUILD_TESTING) + # FIXME: gaudi_add_test(nosetests) is not configurable enough, so I copied a bit of it + _import_nosetests() + add_test(NAME GaudiConfiguration.nose + COMMAND run $<TARGET_FILE:nosetests> -v --with-doctest --with-coverage --cover-package=GaudiConfig2 + ${CMAKE_CURRENT_SOURCE_DIR}/tests/nose) -# Ideally I would use '--cover-min-percentage=100', but the version of nose we -# have is a bit old -set_tests_properties(GaudiConfiguration.nose - PROPERTIES PASS_REGULAR_EXPRESSION "TOTAL .* 100%" - FAIL_REGULAR_EXPRESSION "FAILED") + # Ideally I would use '--cover-min-percentage=100', but the version of nose we + # have is a bit old + set_tests_properties(GaudiConfiguration.nose + PROPERTIES PASS_REGULAR_EXPRESSION "TOTAL .* 100%" + FAIL_REGULAR_EXPRESSION "FAILED") +endif() # Note: The file tools/print_limits.cpp is a ROOT macro, so it is not meant to be compiled diff --git a/GaudiCoreSvc/CMakeLists.txt b/GaudiCoreSvc/CMakeLists.txt index 34efc720ed8b6d39f008a2e53762e97e6753c613..45a2958f33f3861bbbc60628ee9e9062a2e4207e 100644 --- a/GaudiCoreSvc/CMakeLists.txt +++ b/GaudiCoreSvc/CMakeLists.txt @@ -57,7 +57,8 @@ gaudi_add_module(GaudiCoreSvc Boost::system Boost::thread TBB::tbb - ${rt_LIBRARY}) # UNIX only + ${rt_LIBRARY} # UNIX only + ${GAUDI_ATOMIC_LIBS}) foreach(name IN ITEMS base binding bwcompat custom) gaudi_add_executable(test_JOS_${name} SOURCES tests/src/test_JOS/${name}.cpp diff --git a/GaudiExamples/CMakeLists.txt b/GaudiExamples/CMakeLists.txt index b53f9a657f38c7e35494fe52e17331a875dc7062..f87cde823d5b70f67f2f1aafdff7f1c0d8776c63 100644 --- a/GaudiExamples/CMakeLists.txt +++ b/GaudiExamples/CMakeLists.txt @@ -107,7 +107,8 @@ gaudi_add_module(GaudiExamples ROOT::Tree ROOT::RIO ROOT::Hist - ROOT::Net) + ROOT::Net + ${GAUDI_ATOMIC_LIBS}) if(NOT ROOT_VERSION VERSION_LESS "6.20") find_package(ROOT REQUIRED COMPONENTS ROOTHist) diff --git a/GaudiHive/CMakeLists.txt b/GaudiHive/CMakeLists.txt index b7305955684da0aaec6318304192d1aa532588cb..25d629b28963a824ba1c3497a054dcbf81691eeb 100644 --- a/GaudiHive/CMakeLists.txt +++ b/GaudiHive/CMakeLists.txt @@ -48,7 +48,8 @@ gaudi_add_module(GaudiHive ROOT::RIO TBB::tbb Rangev3::rangev3 - ${rt_LIBRARY}) + ${rt_LIBRARY} + ${GAUDI_ATOMIC_LIBS}) # Build executable gaudi_add_executable(makeThesis diff --git a/GaudiKernel/CMakeLists.txt b/GaudiKernel/CMakeLists.txt index cd5bc459a7faa36cb4db0399a830f842495d7941..6bd4d9dd4980aa8894c76579b0c043a58b76c213 100644 --- a/GaudiKernel/CMakeLists.txt +++ b/GaudiKernel/CMakeLists.txt @@ -154,6 +154,7 @@ gaudi_add_library(GaudiKernel cppgsl::cppgsl fmt::fmt nlohmann_json::nlohmann_json + ${GAUDI_ATOMIC_LIBS} ) gaudi_generate_version_header_file(GaudiKernel) target_include_directories(GaudiKernel diff --git a/GaudiKernel/include/Gaudi/Timers.h b/GaudiKernel/include/Gaudi/Timers.h index 9a9f1039e8dfe6e4b1128d62e37735dc9e6622f1..f4a2919797bd2e1928cf2fa0d2c28f2368534976 100644 --- a/GaudiKernel/include/Gaudi/Timers.h +++ b/GaudiKernel/include/Gaudi/Timers.h @@ -1,5 +1,5 @@ /***********************************************************************************\ -* (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations * +* (c) Copyright 1998-2020 CERN for the benefit of the LHCb and ATLAS collaborations * * * * This software is distributed under the terms of the Apache version 2 licence, * * copied verbatim in the file "LICENSE". * @@ -11,7 +11,9 @@ #pragma once #include "Gaudi/Timers/GenericTimer.h" -#include "Gaudi/Timers/RdtscClock.h" +#ifdef __x86_64__ +# include "Gaudi/Timers/RdtscClock.h" +#endif // __x86_64__ #include <chrono> @@ -29,5 +31,9 @@ namespace Gaudi { * \see Gaudi::Timers::GenericTimer * \see Gaudi::Timers::RdtscClock */ +#ifdef __x86_64__ using FastTimer = Timers::GenericTimer<Timers::RdtscClock<std::chrono::microseconds>, std::chrono::microseconds>; +#else + using FastTimer = Timers::GenericTimer<std::chrono::high_resolution_clock, std::chrono::microseconds>; +#endif // __x86_64__ } // namespace Gaudi diff --git a/GaudiKernel/include/Gaudi/Timers/RdtscClock.h b/GaudiKernel/include/Gaudi/Timers/RdtscClock.h index 0a6ad341e25cf9c9ee0512d09eb6eb0ebfb35441..6b1f1df8e172a4eaf8a7a1e2371313231819c191 100644 --- a/GaudiKernel/include/Gaudi/Timers/RdtscClock.h +++ b/GaudiKernel/include/Gaudi/Timers/RdtscClock.h @@ -1,5 +1,5 @@ /***********************************************************************************\ -* (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations * +* (c) Copyright 1998-2020 CERN for the benefit of the LHCb and ATLAS collaborations * * * * This software is distributed under the terms of the Apache version 2 licence, * * copied verbatim in the file "LICENSE". * @@ -10,6 +10,10 @@ \***********************************************************************************/ #pragma once +#ifndef __x86_64__ +# error "<Gaudi/Timers/RdtscClock.h> is only supported on x86" +#endif // not __x86_64__ + #include <chrono> #include <functional> #include <ratio> diff --git a/GaudiKernel/src/contrib/instrset.h b/GaudiKernel/src/contrib/instrset.h index 8fb762ed4645c9b00b4c080e927867af04cc0a1e..f08a5524f6193493d3d5bd837a264b5b15c4d9cf 100644 --- a/GaudiKernel/src/contrib/instrset.h +++ b/GaudiKernel/src/contrib/instrset.h @@ -1,7 +1,7 @@ /**************************** instrset.h ********************************** * Author: Agner Fog * Date created: 2012-05-30 - * Last modified: 2020-04-01 + * Last modified: 2020-11-11 * Version: 2.01.02 * Project: vector class library * Description: @@ -229,7 +229,8 @@ namespace VCL_NAMESPACE { // input: functionnumber = leaf (eax), ecxleaf = subleaf(ecx) // output: output[0] = eax, output[1] = ebx, output[2] = ecx, output[3] = edx static inline void cpuid( int output[4], int functionnumber, int ecxleaf = 0 ) { -#if defined( __GNUC__ ) || defined( __clang__ ) // use inline assembly, Gnu/AT&T syntax +#ifdef __x86_64__ +# if defined( __GNUC__ ) || defined( __clang__ ) // use inline assembly, Gnu/AT&T syntax int a, b, c, d; __asm( "cpuid" : "=a"( a ), "=b"( b ), "=c"( c ), "=d"( d ) : "a"( functionnumber ), "c"( ecxleaf ) : ); output[0] = a; @@ -237,11 +238,11 @@ namespace VCL_NAMESPACE { output[2] = c; output[3] = d; -#elif defined( _MSC_VER ) // Microsoft compiler, intrin.h included - __cpuidex( output, functionnumber, ecxleaf ); // intrinsic function for CPUID +# elif defined( _MSC_VER ) // Microsoft compiler, intrin.h included + __cpuidex( output, functionnumber, ecxleaf ); // intrinsic function for CPUID -#else // unknown platform. try inline assembly with masm/intel syntax - __asm { +# else // unknown platform. try inline assembly with masm/intel syntax + __asm { mov eax, functionnumber mov ecx, ecxleaf cpuid; @@ -250,8 +251,9 @@ namespace VCL_NAMESPACE { mov[esi + 4], ebx mov[esi + 8], ecx mov[esi + 12], edx - } -#endif + } +# endif // compiler/platform +#endif // __x86_64__ } // Define popcount function. Gives sum of bits diff --git a/GaudiProfiling/src/python/CPUFamily.cpp b/GaudiProfiling/src/python/CPUFamily.cpp index 069c49ac4e9526c83dde77ea0537894628442ffc..758b70e7c99457fdd5ddf093c3e218f4cdf23b1b 100644 --- a/GaudiProfiling/src/python/CPUFamily.cpp +++ b/GaudiProfiling/src/python/CPUFamily.cpp @@ -1,5 +1,5 @@ /***********************************************************************************\ -* (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations * +* (c) Copyright 1998-2020 CERN for the benefit of the LHCb and ATLAS collaborations * * * * This software is distributed under the terms of the Apache version 2 licence, * * copied verbatim in the file "LICENSE". * @@ -26,10 +26,14 @@ __asm__ __volatile__( "cpuid" : "=a"( ax ), "=b"( bx ), "=c"( cx ), "=d"( dx ) : "a"( func ) ); bool is_nehalem() { +#ifdef __x86_64__ int a, b, c, d; cpuid( 1, a, b, c, d ); int sse4_2_mask = 1 << 20; return ( c & sse4_2_mask ); +#else + return false; +#endif // __x86_64__ } const char* CPUFamily() { diff --git a/cmake/GaudiAtomicLibs.cmake b/cmake/GaudiAtomicLibs.cmake new file mode 100644 index 0000000000000000000000000000000000000000..daad8a3db40dbd9d2c13c984a5145041a08bf3e1 --- /dev/null +++ b/cmake/GaudiAtomicLibs.cmake @@ -0,0 +1,64 @@ +##################################################################################### +# (c) Copyright 2020 CERN for the benefit of the LHCb and ATLAS collaborations # +# # +# This software is distributed under the terms of the Apache version 2 licence, # +# copied verbatim in the file "LICENSE". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +##################################################################################### + +#[========================================================================[.rst: +Gaudi Atomic Library Setup +-------------------------- + +This module sets up the `GAUDI_ATOMIC_LIBS` variable to (optionally) point at +the library providing atomic function calls for the compiled code. + +On certain platforms, like armv7l, GCC needs to be instructed explicitly to +link against `libatomic.so`, to build code that uses atomic function calls. +The code tries to smartly figure out whether it needs to use `libatomic.so` or +not, and where it should take it from. But in case it fails, it is possible to +override the `GAUDI_ATOMIC_LIB` cache variable to force the usage of a +particular library. (Or no library at all.) + +The code here was taken from ROOT's CMake configuration. Which itself was based +on LLVM's CMake configuration. +#]========================================================================] + +# Include the necessary module(s). +include(CheckCXXSourceCompiles) + +# Check whether 32 and 64-bit atomic operations can be performed without using +# an extra library on the build platform. +check_cxx_source_compiles(" +#include <atomic> +#include <cstdint> +int main() { + std::atomic<int> a1; + int a1val = a1.load(); + (void)a1val; + std::atomic<uint64_t> a2; + uint64_t a2val = a2.load(std::memory_order_relaxed); + (void)a2val; + return 0; +} +" GAUDI_HAVE_CXX_ATOMICS_WITHOUT_LIB) + +# Set up the GAUDI_ATOMIC_LIBS variable. +set(GAUDI_ATOMIC_LIBS) +if(GAUDI_HAVE_CXX_ATOMICS_WITHOUT_LIB) + message(STATUS "Explicit atomic library usage does not seem to be necessary") +else() + find_library(GAUDI_ATOMIC_LIB NAMES atomic + HINTS ENV LD_LIBRARY_PATH + DOC "Path to the atomic library to use during the build") + mark_as_advanced(GAUDI_ATOMIC_LIB) + if(GAUDI_ATOMIC_LIB) + set(GAUDI_ATOMIC_LIBS ${GAUDI_ATOMIC_LIB}) + message(STATUS "Using atomic library: ${GAUDI_ATOMIC_LIB}") + else() + message(WARNING "No atomic library found. The build will likely fail.") + endif() +endif()