From 677f60da9487c4d00f83b6024b195999d3dedae1 Mon Sep 17 00:00:00 2001 From: Simon Praetorius Date: Tue, 13 Jun 2017 12:56:39 +0200 Subject: [PATCH] initfile singleton made thread-safe (at least the construction --- AMDiS/cmake3/AMDIS.cmake.in | 25 ++++---- AMDiS/cmake3/CMakeLists.txt | 17 ++++-- AMDiS/cmake3/muparser.cmake | 6 +- AMDiS/cmake3/target_enable_boost.cmake | 2 +- AMDiS/cmake3/target_enable_mtl4.cmake | 53 ++++++++-------- AMDiS/src/DOFVector.hh | 4 ++ AMDiS/src/ElInfo1d.cc | 2 - AMDiS/src/ElInfo2d.cc | 3 +- AMDiS/src/ElInfo3d.cc | 2 - AMDiS/src/Global.cc | 1 - AMDiS/src/Initfile.cc | 21 +++---- AMDiS/src/Initfile.h | 83 +++++++++++--------------- configure.sh | 8 +-- 13 files changed, 102 insertions(+), 125 deletions(-) diff --git a/AMDiS/cmake3/AMDIS.cmake.in b/AMDiS/cmake3/AMDIS.cmake.in index 5f4aa43a..b98c63c2 100644 --- a/AMDiS/cmake3/AMDIS.cmake.in +++ b/AMDiS/cmake3/AMDIS.cmake.in @@ -1,4 +1,3 @@ -set(AMDIS_NEED_CXX11 @ENABLE_CXX11@) set(AMDIS_NEED_UMFPACK @ENABLE_UMFPACK@) set(AMDIS_NEED_COMPRESSION @ENABLE_COMPRESSION@) set(AMDIS_NEED_EXTENSIONS @ENABLE_EXTENSIONS@) @@ -18,19 +17,17 @@ add_library(AMDiS ALIAS amdis_base) target_compile_definitions(amdis_base INTERFACE) -if (AMDIS_NEED_CXX11) - target_enable_cxx14(SUPPORTS_CXX14 amdis_base INTERFACE) - if (NOT SUPPORTS_CXX14) - target_enable_cxx11(SUPPORTS_CXX11 amdis_base INTERFACE) - endif () - - if (NOT SUPPORTS_CXX11 AND NOT SUPPORTS_CXX14) - message(FATAL_ERROR "AMDiS was compiled with c++11 support, but the current compiler does not support this feature!") - endif () - target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX11=1) -else () - target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX11=0) -endif (AMDIS_NEED_CXX11) + +target_enable_cxx14(SUPPORTS_CXX14 amdis_base INTERFACE) +if (NOT SUPPORTS_CXX14) + target_enable_cxx11(SUPPORTS_CXX11 amdis_base INTERFACE) +endif () + +if (NOT SUPPORTS_CXX11 AND NOT SUPPORTS_CXX14) + message(FATAL_ERROR "AMDiS was compiled with c++11 support, but the current compiler does not support this feature!") +endif () +target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX11=1) + # try to detect the AMDiS include directory diff --git a/AMDiS/cmake3/CMakeLists.txt b/AMDiS/cmake3/CMakeLists.txt index fb308342..11d5a09e 100644 --- a/AMDiS/cmake3/CMakeLists.txt +++ b/AMDiS/cmake3/CMakeLists.txt @@ -23,12 +23,19 @@ add_library(AMDiS::base ALIAS amdis_base) target_include_directories(amdis_base INTERFACE ${SOURCE_DIR}) target_compile_definitions(amdis_base INTERFACE) -target_enable_cxx11(ENABLE_CXX11 amdis_base INTERFACE) -if (ENABLE_CXX11) - target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX11=1) + +target_enable_cxx14(SUPPORTS_CXX14 amdis_base INTERFACE) +if (SUPPORTS_CXX14) + target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX14=1) else () - target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX11=0) -endif (ENABLE_CXX11) + target_enable_cxx11(SUPPORTS_CXX11 amdis_base INTERFACE) +endif () + +if (NOT SUPPORTS_CXX11 AND NOT SUPPORTS_CXX14) + message(FATAL_ERROR "AMDiS needs c++11 support, but the current compiler does not support this feature!") +endif () +target_compile_definitions(amdis_base INTERFACE AMDIS_HAS_CXX11=1) + target_enable_mtl4(amdis_base INTERFACE) target_enable_boost(amdis_base INTERFACE) diff --git a/AMDiS/cmake3/muparser.cmake b/AMDiS/cmake3/muparser.cmake index 016a16da..82910f8c 100644 --- a/AMDiS/cmake3/muparser.cmake +++ b/AMDiS/cmake3/muparser.cmake @@ -17,10 +17,8 @@ add_library(muparser STATIC target_include_directories(muparser PUBLIC ${MUPARSER_INCLUDE_DIR}) set_property(TARGET muparser PROPERTY POSITION_INDEPENDENT_CODE ON) -if (ENABLE_CXX11) - target_enable_cxx11(MUPARSER_ENABLE_CXX11 muparser PRIVATE) - target_compile_definitions(muparser PRIVATE AMDIS_HAS_CXX11=1) -endif (ENABLE_CXX11) +target_enable_cxx11(MUPARSER_ENABLE_CXX11 muparser PRIVATE) +target_compile_definitions(muparser PRIVATE AMDIS_HAS_CXX11=1) # specify how to install this target: # ----------------------------------- diff --git a/AMDiS/cmake3/target_enable_boost.cmake b/AMDiS/cmake3/target_enable_boost.cmake index 9febfa5e..443a374d 100644 --- a/AMDiS/cmake3/target_enable_boost.cmake +++ b/AMDiS/cmake3/target_enable_boost.cmake @@ -13,7 +13,7 @@ macro(target_enable_boost _TARGET_ _SCOPE_) endif (BOOST_LIBRARYDIR) set(BOOST_VERSION "1.48") - set(BOOST_LIBS_REQUIRED system iostreams filesystem program_options date_time) + set(BOOST_LIBS_REQUIRED system iostreams filesystem program_options date_time thread) if (WIN32) list(APPEND BOOST_LIBS_REQUIRED zlib) if (ENABLE_COMPRESSION OR AMDIS_NEED_COMPRESSION) diff --git a/AMDiS/cmake3/target_enable_mtl4.cmake b/AMDiS/cmake3/target_enable_mtl4.cmake index 13ac696d..7f18a58c 100644 --- a/AMDiS/cmake3/target_enable_mtl4.cmake +++ b/AMDiS/cmake3/target_enable_mtl4.cmake @@ -1,35 +1,32 @@ macro(target_enable_mtl4 _TARGET_ _SCOPE_) - if (${ARGC} GREATER 2) - set(LINK_EXECUTABLE ON) - else () - set(LINK_EXECUTABLE OFF) - endif () + if (${ARGC} GREATER 2) + set(LINK_EXECUTABLE ON) + else () + set(LINK_EXECUTABLE OFF) + endif () - add_library(mtl4 INTERFACE) + add_library(mtl4 INTERFACE) - if (LINK_EXECUTABLE) - target_include_directories(${_TARGET_} ${_SCOPE_} ${AMDIS_INCLUDE_DIR}/mtl4) - else () - target_include_directories(${_TARGET_} ${_SCOPE_} ${BASE_DIR}/lib/mtl4) - endif (LINK_EXECUTABLE) - target_compile_definitions(${_TARGET_} ${_SCOPE_} MTL_ASSERT_FOR_THROW=1) + if (LINK_EXECUTABLE) + target_include_directories(${_TARGET_} ${_SCOPE_} ${AMDIS_INCLUDE_DIR}/mtl4) + else () + target_include_directories(${_TARGET_} ${_SCOPE_} ${BASE_DIR}/lib/mtl4) + endif (LINK_EXECUTABLE) + target_compile_definitions(${_TARGET_} ${_SCOPE_} MTL_ASSERT_FOR_THROW=1) - if (ENABLE_CXX11) - set (CXX_ELEVEN_FEATURE_LIST "MOVE" "AUTO" "RANGEDFOR" "INITLIST" "STATICASSERT" "DEFAULTIMPL") - foreach (feature ${CXX_ELEVEN_FEATURE_LIST}) - target_compile_definitions(${_TARGET_} ${_SCOPE_} MTL_WITH_${feature}) - endforeach () - endif (ENABLE_CXX11) + set (CXX_ELEVEN_FEATURE_LIST "MOVE" "AUTO" "RANGEDFOR" "INITLIST" "STATICASSERT" "DEFAULTIMPL") + foreach (feature ${CXX_ELEVEN_FEATURE_LIST}) + target_compile_definitions(${_TARGET_} ${_SCOPE_} MTL_WITH_${feature}) + endforeach () - if (ENABLE_OPENMP) - find_package(OpenMP REQUIRED) - if (OPENMP_FOUND) - target_compile_definitions(${_TARGET_} ${_SCOPE_} MTL_WITH_OPENMP) - target_compile_options(${_TARGET_} ${_SCOPE_} ${OpenMP_CXX_FLAGS}) - else () - message(FATAL_ERROR "OpenMP not found") - endif (OPENMP_FOUND) - endif (ENABLE_OPENMP) - + if (ENABLE_OPENMP) + find_package(OpenMP REQUIRED) + if (OPENMP_FOUND) + target_compile_definitions(${_TARGET_} ${_SCOPE_} MTL_WITH_OPENMP) + target_compile_options(${_TARGET_} ${_SCOPE_} ${OpenMP_CXX_FLAGS}) + else () + message(FATAL_ERROR "OpenMP not found") + endif (OPENMP_FOUND) + endif (ENABLE_OPENMP) endmacro(target_enable_mtl4) diff --git a/AMDiS/src/DOFVector.hh b/AMDiS/src/DOFVector.hh index 4c229e78..b05af7cd 100644 --- a/AMDiS/src/DOFVector.hh +++ b/AMDiS/src/DOFVector.hh @@ -124,8 +124,10 @@ namespace AMDiS { { this->name = n; this->feSpace = f; + if (this->feSpace && this->feSpace->getAdmin()) (this->feSpace->getAdmin())->addDOFIndexed(this); + this->boundaryManager = new BoundaryManager(f); #ifdef HAVE_PARALLEL_DOMAIN_AMDIS if (addToSynch && Parallel::MeshDistributor::globalMeshDistributor != NULL) @@ -140,6 +142,8 @@ namespace AMDiS { if ( Parallel::MeshDistributor::globalMeshDistributor != NULL) Parallel::MeshDistributor::globalMeshDistributor->removeInterchangeVector(this); #endif + + #pragma omp critical if (this->feSpace && this->feSpace->getAdmin()) (this->feSpace->getAdmin())->removeDOFIndexed(this); diff --git a/AMDiS/src/ElInfo1d.cc b/AMDiS/src/ElInfo1d.cc index e4836a05..71a21d1f 100644 --- a/AMDiS/src/ElInfo1d.cc +++ b/AMDiS/src/ElInfo1d.cc @@ -161,8 +161,6 @@ namespace AMDiS { double length = (coord[1][0] - a); int dim = mesh->getDim(); - static DimVec vec(dim, NO_INIT); - TEST_EXIT_DBG(lambda)("lambda must not be NULL\n"); TEST_EXIT_DBG(dim == 1)("dim!=1\n"); TEST_EXIT_DBG(dimOfWorld == dim)("not yet for DIM != DIM_OF_WORLD\n"); diff --git a/AMDiS/src/ElInfo2d.cc b/AMDiS/src/ElInfo2d.cc index 7d7e2119..3bc7d64d 100644 --- a/AMDiS/src/ElInfo2d.cc +++ b/AMDiS/src/ElInfo2d.cc @@ -679,7 +679,6 @@ namespace AMDiS { DimVec > edge(mesh->getDim(), NO_INIT); WorldVector x; - static DimVec vec(mesh->getDim(), NO_INIT); int dim = mesh->getDim(); @@ -875,4 +874,4 @@ namespace AMDiS { { return getSubElemCoordsMat(degree); } -} \ No newline at end of file +} diff --git a/AMDiS/src/ElInfo3d.cc b/AMDiS/src/ElInfo3d.cc index 87fd26af..f029d67a 100644 --- a/AMDiS/src/ElInfo3d.cc +++ b/AMDiS/src/ElInfo3d.cc @@ -336,8 +336,6 @@ namespace AMDiS { WorldVector x; double x0, det, det0, det1, det2; - static DimVec vec(mesh->getDim(), NO_INIT); - TEST_EXIT_DBG(lambda)("lambda must not be NULL\n"); int dim = mesh->getDim(); diff --git a/AMDiS/src/Global.cc b/AMDiS/src/Global.cc index 42fc8e60..8af28c51 100644 --- a/AMDiS/src/Global.cc +++ b/AMDiS/src/Global.cc @@ -317,7 +317,6 @@ namespace AMDiS { int d = -1; // get dimension - TEST_EXIT(Parameters::initialized())("Parameters not initialized!\n"); Parameters::get("dimension of world",d,0); TEST_EXIT(d > 0)("Cannot initialize dimension!\n"); TEST_EXIT((d == 1) || (d == 2) || (d == 3))("Invalid world dimension %d!\n",d); diff --git a/AMDiS/src/Initfile.cc b/AMDiS/src/Initfile.cc index bd7976ba..222f7f60 100644 --- a/AMDiS/src/Initfile.cc +++ b/AMDiS/src/Initfile.cc @@ -67,17 +67,13 @@ namespace AMDiS { } } - Initfile* Initfile::singlett = NULL; - std::set Initfile::fn_include_list; - - /// initialize singleton object an global parameters + /// initialize singleton object and global parameters void Initfile::init(std::string in) { - initIntern(); - fn_include_list.clear(); - singlett->read(in); - singlett->getInternalParameters(); + getIncludeList().clear(); + singlett().read(in); + singlett().getInternalParameters(); } @@ -85,13 +81,13 @@ namespace AMDiS { void Initfile::read(std::string fn, bool force) { // read file if its not parsed already - if (fn_include_list.find(fn) == fn_include_list.end() || force) { + if (getIncludeList().find(fn) == getIncludeList().end() || force) { std::ifstream inputFile; inputFile.open(fn.c_str(), std::ios::in); if (!inputFile.is_open()) throw runtime_error("init-file '" + fn + "' cannot be opened for reading"); - fn_include_list.insert(fn); + getIncludeList().insert(fn); read(inputFile); } } @@ -233,8 +229,6 @@ namespace AMDiS { void Initfile::readArgv(std::string parameters, int debugInfo) { - initIntern(); - char seperator = ';'; typedef boost::escaped_list_separator TokenizerFunc; typedef boost::tokenizer Tokenizer; @@ -286,8 +280,7 @@ namespace AMDiS { /// print all parameters to std::cout void Initfile::printParameters() { - initIntern(); - for (Initfile::iterator it = singlett->begin(); it != singlett->end(); it++) + for (Initfile::iterator it = singlett().begin(); it != singlett().end(); it++) std::cout << (*it).first << " => " << (*it).second << std::endl; } diff --git a/AMDiS/src/Initfile.h b/AMDiS/src/Initfile.h index add610cf..4f2331b0 100644 --- a/AMDiS/src/Initfile.h +++ b/AMDiS/src/Initfile.h @@ -37,6 +37,7 @@ #include #include +#include // requires c++14 #include @@ -422,18 +423,19 @@ namespace AMDiS { template static void get(const std::string tag, T& value, int debugInfo = -1) { - initIntern(); +// boost::shared_lock lock(singlett().mutex_); + if (debugInfo == -1) - debugInfo = singlett->getMsgInfo(); + debugInfo = singlett().getMsgInfo(); else { int swap(debugInfo); - debugInfo = singlett->getMsgInfo(); - singlett->msgInfo=swap; + debugInfo = singlett().getMsgInfo(); + singlett().msgInfo=swap; } std::string valStr; try { - int error_code = singlett->checkedGet(tag, valStr); + int error_code = singlett().checkedGet(tag, valStr); if (error_code == 0) { valStr = trim(valStr); detail::convert(valStr, value); @@ -454,7 +456,7 @@ namespace AMDiS { std::cout << "Parameter '" << tag << "'" << " initialized with: " << value << std::endl; } - singlett->msgInfo = debugInfo; + singlett().msgInfo = debugInfo; } @@ -471,8 +473,7 @@ namespace AMDiS { std::map &pm, int debugInfo = -1) { - initIntern(); - for (Initfile::iterator it = singlett->begin(); it != singlett->end(); it++){ + for (Initfile::iterator it = singlett().begin(); it != singlett().end(); it++){ std::string longTag= (*it).first ; std::string value=(*it).second; if(longTag.length()>tag.length() && @@ -497,10 +498,12 @@ namespace AMDiS { /// return InitEntry object for tag tag static InitEntry get(const std::string tag) { +// boost::shared_lock lock(singlett().mutex_); + InitEntry result; std::string valStr; - int error_code = singlett->checkedGet(tag, valStr); + int error_code = singlett().checkedGet(tag, valStr); if (error_code == 0) { valStr = trim(valStr); result = InitEntry(valStr); @@ -524,15 +527,16 @@ else if(error_code == TAG_NOT_FOUND_BREAK) template static void set(const std::string tag, T& value, int debugInfo= -1) { - initIntern(); +// boost::unique_lock lock(singlett().mutex_); + if (debugInfo == -1) - debugInfo = singlett->getMsgInfo(); + debugInfo = singlett().getMsgInfo(); std::string swap = ""; detail::convert(value, swap); - (*singlett)[trim(tag)] = swap; + singlett()[trim(tag)] = swap; // update msg parameters msgInfo, msgWait, paramInfo - singlett->getInternalParameters(); + singlett().getInternalParameters(); if (debugInfo == 2) std::cout << "Parameter '" << tag << "'" << " set to: " << value << std::endl; @@ -554,28 +558,14 @@ else if(error_code == TAG_NOT_FOUND_BREAK) /// Returns specified info level static int getMsgInfo() { - return (singlett != NULL) ? singlett->msgInfo : 0; + return singlett().msgInfo; } /// Returns specified wait value static int getMsgWait() { - return (singlett != NULL) ? singlett->msgWait : 0; - } - - - /// Checks whether parameters are initialized. if not, call init() - static bool initialized() - { - return (singlett != NULL); - } - - - /// return pointer to singleton - static Initfile *getSingleton() - { - return singlett; + return singlett().msgWait; } @@ -586,21 +576,24 @@ else if(error_code == TAG_NOT_FOUND_BREAK) /// clear data in singleton static void clearData() { - initIntern(); - singlett->clear(); + singlett().clear(); } - + /// save singlett-data to file with filename fn static void save(std::string fn) { - initIntern(); - singlett->write(fn); + singlett().write(fn); } + - static std::set< std::string > getIncludeList(){ - return fn_include_list; + // list of included filenames + static std::set< std::string >& getIncludeList() + { + static std::set< std::string > include_list; + return include_list; } + protected: Initfile() : msgInfo(0), @@ -609,22 +602,14 @@ protected: breakOnMissingTag(0) {} - - static void initIntern() + /// return reference to singleton + static Initfile& singlett() { - if (singlett == NULL) - singlett = new Initfile; + static Initfile singlett_{}; + return singlett_; } - /// list of processed files - static std::set< std::string > fn_include_list; - - - /// pointer to the singleton that contains the data - static Initfile* singlett; - - /// return the value of the given tag or throws an exception if the tag /// does not exist int checkedGet(const std::string& tag, std::string &valStr) const @@ -671,6 +656,8 @@ protected: void getInternalParameters(); int msgInfo, msgWait, paramInfo, breakOnMissingTag; + +// mutable boost::shared_mutex mutex_; }; typedef Initfile Parameters; diff --git a/configure.sh b/configure.sh index b3e18f44..cd193f64 100755 --- a/configure.sh +++ b/configure.sh @@ -15,7 +15,7 @@ ENABLE_COMPRESSION="OFF" ENABLE_PARALLEL="OFF" BOOST_PREFIX="${BOOST_ROOT}" DOWNLOAD_BOOST="0" -BOOST_VERSION="1.62.0" +BOOST_VERSION="1.64.0" PETSC_PREFIX="${PETSC_DIR}" DOWNLOAD_PETSC="0" PETSC_VERSION="3.5.4" @@ -196,11 +196,11 @@ if [ "${DOWNLOAD_BOOST}" -eq "1" ]; then BOOST_PREFIX=${SRC_DIR}/packages/boost/${BOOST_VERSION} cd /tmp/src/boost - ./bootstrap.sh --prefix=${BOOST_PREFIX} --with-libraries=system,iostreams,filesystem,program_options,date_time,test + ./bootstrap.sh --prefix=${BOOST_PREFIX} --with-libraries=system,iostreams,filesystem,program_options,date_time,test,thread if [ "${ENABLE_COMPRESSION}" = "ON" ]; then - ./b2 -s cxxflags="-std=c++11" --build-type=minimal variant=release install + ./b2 -s cxxflags="-std=c++14" --build-type=minimal variant=release install else - ./b2 -s NO_BZIP2=1 -s NO_ZLIB=1 cxxflags="-std=c++11" --build-type=minimal variant=release install + ./b2 -s NO_BZIP2=1 -s NO_ZLIB=1 cxxflags="-std=c++14" --build-type=minimal variant=release install fi rm -rf /tmp/src/boost fi -- GitLab