From ca6b5426a74ad2ccca24956dfb64dfd0033057f7 Mon Sep 17 00:00:00 2001 From: Mark Abraham Date: Fri, 29 Jan 2021 16:24:39 +0100 Subject: [PATCH] Replace gmx::Mutex with std::mutex We use no mutexes during the MD loop, so performance is not a serious consideration and we should simplify by using std components. Eliminated components of thread-MPI that are now unused. In particular, this reduces the cross-dependencies between the libgromacs and threadMPI libraries. Minor style improvements around set_over_alloc_dd. Part of #3892 --- cmake/ThreadMPI.cmake | 4 - .../thread_mpi/include/thread_mpi/mutex.h | 173 ------------ .../include/thread_mpi/system_error.h | 77 ------ src/external/thread_mpi/src/system_error.cpp | 48 ---- .../commandline/cmdlineprogramcontext.cpp | 10 +- .../commandline/cmdlineprogramcontext.h | 2 - src/gromacs/domdec/domdec.cpp | 4 +- src/gromacs/fft/fft5d.cpp | 8 +- src/gromacs/fft/fft_fftw3.cpp | 7 +- src/gromacs/fileio/gmxfio.cpp | 8 +- src/gromacs/fileio/timecontrol.cpp | 15 +- src/gromacs/gpu_utils/clfftinitializer.cpp | 11 +- src/gromacs/nbnxm/opencl/nbnxm_ocl.cpp | 4 +- src/gromacs/pulling/pull.cpp | 6 +- src/gromacs/selection/nbsearch.cpp | 10 +- src/gromacs/utility/exceptions.cpp | 8 +- src/gromacs/utility/fatalerror.cpp | 8 +- src/gromacs/utility/futil.cpp | 8 +- .../utility/keyvaluetreeserializer.cpp | 11 +- src/gromacs/utility/mutex.h | 64 ----- src/gromacs/utility/smalloc.cpp | 15 +- src/gromacs/utility/smalloc.h | 5 +- src/gromacs/utility/tests/CMakeLists.txt | 3 +- src/gromacs/utility/tests/mutex.cpp | 246 ------------------ src/testutils/include/testutils/testoptions.h | 3 +- src/testutils/testoptions.cpp | 8 +- 26 files changed, 72 insertions(+), 694 deletions(-) delete mode 100644 src/external/thread_mpi/include/thread_mpi/mutex.h delete mode 100644 src/external/thread_mpi/include/thread_mpi/system_error.h delete mode 100644 src/external/thread_mpi/src/system_error.cpp delete mode 100644 src/gromacs/utility/mutex.h delete mode 100644 src/gromacs/utility/tests/mutex.cpp diff --git a/cmake/ThreadMPI.cmake b/cmake/ThreadMPI.cmake index c0847c429e..a013fb164a 100644 --- a/cmake/ThreadMPI.cmake +++ b/cmake/ThreadMPI.cmake @@ -220,10 +220,6 @@ MACRO(TMPI_GET_SOURCE_LIST SRC_VARIABLE SRC_ROOT) list(APPEND ${SRC_VARIABLE} ${SRC_ROOT}/winthreads.cpp) endif () - if (TMPI_CXX_LIB) - list(APPEND ${SRC_VARIABLE} ${SRC_ROOT}/system_error.cpp) - endif () - if (TMPI_ENABLED) list(APPEND ${SRC_VARIABLE} ${SRC_ROOT}/alltoall.cpp ${SRC_ROOT}/p2p_protocol.cpp diff --git a/src/external/thread_mpi/include/thread_mpi/mutex.h b/src/external/thread_mpi/include/thread_mpi/mutex.h deleted file mode 100644 index fc5381a754..0000000000 --- a/src/external/thread_mpi/include/thread_mpi/mutex.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - This source code file is part of thread_mpi. - Written by Sander Pronk, Erik Lindahl, and possibly others. - - Copyright (c) 2009, Sander Pronk, Erik Lindahl. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - 1) Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2) Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - 3) Neither the name of the copyright holders nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY US ''AS IS'' AND ANY - EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL WE BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - If you want to redistribute modifications, please consider that - scientific software is very special. Version control is crucial - - bugs must be traceable. We will be happy to consider code for - inclusion in the official distribution, but derived work should not - be called official thread_mpi. Details are found in the README & COPYING - files. - */ - -/** \file - * - * \brief mutex objects with C++11 API compatibility. - * - * This header contains classes mutex and lock_guard, used in C++ mutex - * implementations safe for exceptions. - */ - -#ifndef TMPI_MUTEX_H_ -#define TMPI_MUTEX_H_ - -#include "visibility.h" -#include "system_error.h" -#include "threads.h" - -namespace tMPI -{ -/*! \brief A lock guard class that allows for the simple management of - mutexes. C++11 compatible. - - In C++, mutexes would normally have to be unlocked with explicit - exception handlers and unlock statements. This class automates that - by handling the mutex unlock in a destructor. The constructor locks - the mutex. - - Usage example: - tMPI::mutex mtx; - void do_count() - { - tMPI::lock_guard lock(mtx); - count += 1; - } - */ -template class TMPI_EXPORT lock_guard -{ - public: - //! Lockable type that this lock operates on. - typedef Mutex mutex_type; - /*! \brief The constructor, which locks the mutex. - - \param m The exisiting (globally accessible) mutex to lock. */ - explicit lock_guard(mutex_type &m) : m_(m) - { - m_.lock(); - } - //lock_guard(mutex_type &m, adopt_lock_t t); - - /*! \brief The destructor, which unlocks the mutex */ - ~lock_guard() - { - m_.unlock(); - } - private: - // forbid copy constructor & assignment - lock_guard(const lock_guard &l); - lock_guard &operator=(const lock_guard &l); - - mutex_type &m_; -}; - -/*! \brief A basic mutex class with C++11 compatibility. */ -class TMPI_EXPORT mutex -{ - public: - //! Type of the native mutex handle. - typedef tMPI_Thread_mutex_t* native_handle_type; - - /*! \brief The constructor. - - Throws a tMPI::system_error exception upon failure. */ - mutex() - { - int ret = tMPI_Thread_mutex_init(&handle_); - if (ret) - { - throw system_error(ret); - } - } - - /*! \brief The destructor.*/ - ~mutex() - { - tMPI_Thread_mutex_destroy(&handle_); - } - - /*! \brief The lock function. - - Throws a tMPI::system_error exception upon failure. */ - void lock() - { - int ret = tMPI_Thread_mutex_lock(&handle_); - if (ret) - { - throw system_error(ret); - } - } - - /*! \brief The try_lock function. - - \return true if the lock was locked successfully, false if - another thread owned it, and implementation-specific if - already held by this thread. Do not rely on the return code - if the calling thread could already hold this lock. */ - bool try_lock() - { - if (tMPI_Thread_mutex_trylock(&handle_)) - { - return false; - } - return true; - } - - /*! \brief The unlock function. - - Throws a tMPI::system_error exception upon failure. */ - void unlock() - { - int ret = tMPI_Thread_mutex_unlock(&handle_); - if (ret) - { - throw system_error(ret); - } - } - - //! Returns the native handle for this mutex. - native_handle_type native_handle() { return &handle_; } - private: - // forbid copy constructor & assignment - mutex(const mutex &m); - mutex &operator=(const mutex &m); - - tMPI_Thread_mutex_t handle_; -}; -} - -#endif /* TMPI_MUTEX_H_ */ diff --git a/src/external/thread_mpi/include/thread_mpi/system_error.h b/src/external/thread_mpi/include/thread_mpi/system_error.h deleted file mode 100644 index f425f7c68b..0000000000 --- a/src/external/thread_mpi/include/thread_mpi/system_error.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - This source code file is part of thread_mpi. - Written by Sander Pronk, Erik Lindahl, and possibly others. - - Copyright (c) 2009, Sander Pronk, Erik Lindahl. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - 1) Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2) Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - 3) Neither the name of the copyright holders nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY US ''AS IS'' AND ANY - EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL WE BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - If you want to redistribute modifications, please consider that - scientific software is very special. Version control is crucial - - bugs must be traceable. We will be happy to consider code for - inclusion in the official distribution, but derived work should not - be called official thread_mpi. Details are found in the README & COPYING - files. - */ - -/** \file - * \brief A C++11 compatible system_error class for reporting exceptions - * - * This header contains class definitions for system_error. - */ - -#ifndef TMPI_SYSTEM_ERROR_H_ -#define TMPI_SYSTEM_ERROR_H_ - -#include - -#include "visibility.h" - -namespace tMPI -{ -/*! \brief Subset of the C++11 system_error class - - Only contains the errno-based constructor. */ -class system_error : public std::runtime_error -{ - public: - //! Type to represent error codes within this class. - typedef int error_code; - - //system_error(error_code ec, const std::string& what_arg); - //system_error(error_code ec, const char* what_arg); - /*! \brief Constuctor that takes an system error number */ - explicit system_error(error_code ec); - - /*! \brief Returns the error code */ - const error_code &code() const - { - return ec_; - } - private: - error_code ec_; -}; -} - -#endif /* TMPI_SYSTEM_ERROR_H_ */ diff --git a/src/external/thread_mpi/src/system_error.cpp b/src/external/thread_mpi/src/system_error.cpp deleted file mode 100644 index 46d116c721..0000000000 --- a/src/external/thread_mpi/src/system_error.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - This source code file is part of thread_mpi. - Written by Sander Pronk, Erik Lindahl, and possibly others. - - Copyright (c) 2009, Sander Pronk, Erik Lindahl. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - 1) Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2) Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - 3) Neither the name of the copyright holders nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY US ''AS IS'' AND ANY - EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL WE BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - If you want to redistribute modifications, please consider that - scientific software is very special. Version control is crucial - - bugs must be traceable. We will be happy to consider code for - inclusion in the official distribution, but derived work should not - be called official thread_mpi. Details are found in the README & COPYING - files. - */ - -#include -#include -#include -#include -#include -#include "thread_mpi/system_error.h" - -tMPI::system_error::system_error(error_code ec) - : runtime_error(std::string(std::strerror(ec))), ec_(ec) -{ -} diff --git a/src/gromacs/commandline/cmdlineprogramcontext.cpp b/src/gromacs/commandline/cmdlineprogramcontext.cpp index dd573cc1ab..5c4b5b89f0 100644 --- a/src/gromacs/commandline/cmdlineprogramcontext.cpp +++ b/src/gromacs/commandline/cmdlineprogramcontext.cpp @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team. - * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,13 +52,13 @@ #include #include +#include #include #include #include "buildinfo.h" #include "gromacs/utility/exceptions.h" #include "gromacs/utility/gmxassert.h" -#include "gromacs/utility/mutex.h" #include "gromacs/utility/path.h" #include "gromacs/utility/stringutil.h" @@ -306,7 +306,7 @@ public: mutable std::string fullBinaryPath_; mutable std::string installationPrefix_; mutable bool bSourceLayout_; - mutable Mutex binaryPathMutex_; + mutable std::mutex binaryPathMutex_; }; CommandLineProgramContext::Impl::Impl() : programName_("GROMACS"), bSourceLayout_(false) {} @@ -388,14 +388,14 @@ const char* CommandLineProgramContext::commandLine() const const char* CommandLineProgramContext::fullBinaryPath() const { - lock_guard lock(impl_->binaryPathMutex_); + std::lock_guard lock(impl_->binaryPathMutex_); impl_->findBinaryPath(); return impl_->fullBinaryPath_.c_str(); } InstallationPrefixInfo CommandLineProgramContext::installationPrefix() const { - lock_guard lock(impl_->binaryPathMutex_); + std::lock_guard lock(impl_->binaryPathMutex_); if (impl_->installationPrefix_.empty()) { impl_->findBinaryPath(); diff --git a/src/gromacs/commandline/cmdlineprogramcontext.h b/src/gromacs/commandline/cmdlineprogramcontext.h index 56323ddb43..70d06df13f 100644 --- a/src/gromacs/commandline/cmdlineprogramcontext.h +++ b/src/gromacs/commandline/cmdlineprogramcontext.h @@ -187,7 +187,6 @@ public: * Returns the full path of the running binary. * * \throws std::bad_alloc if out of memory. - * \throws tMPI::system_error on thread synchronization errors. * * Returns argv[0] if there was an error in finding the absolute path. */ @@ -196,7 +195,6 @@ public: * Returns the installation prefix (for finding \Gromacs data files). * * \throws std::bad_alloc if out of memory. - * \throws tMPI::system_error on thread synchronization errors. * * Returns a hardcoded path set during configuration time if there is * an error in finding the library data files. diff --git a/src/gromacs/domdec/domdec.cpp b/src/gromacs/domdec/domdec.cpp index fe24a703b0..e54203bcbf 100644 --- a/src/gromacs/domdec/domdec.cpp +++ b/src/gromacs/domdec/domdec.cpp @@ -4,7 +4,7 @@ * Copyright (c) 2005,2006,2007,2008,2009 by the GROMACS development team. * Copyright (c) 2010,2011,2012,2013,2014 by the GROMACS development team. * Copyright (c) 2015,2016,2017,2018,2019 by the GROMACS development team. - * Copyright (c) 2020, by the GROMACS development team, led by + * Copyright (c) 2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -3122,7 +3122,7 @@ gmx_domdec_t* DomainDecompositionBuilder::Impl::build(LocalAtomSetManager* atomS } /* Set overallocation to avoid frequent reallocation of arrays */ - set_over_alloc_dd(TRUE); + set_over_alloc_dd(true); dd->atomSets = atomSets; diff --git a/src/gromacs/fft/fft5d.cpp b/src/gromacs/fft/fft5d.cpp index 03fb8da297..71020eec6b 100644 --- a/src/gromacs/fft/fft5d.cpp +++ b/src/gromacs/fft/fft5d.cpp @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 2009-2018, The GROMACS development team. - * Copyright (c) 2019,2020, by the GROMACS development team, led by + * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -86,11 +86,13 @@ FILE* debug = 0; #if GMX_FFT_FFTW3 +# include + # include "gromacs/utility/exceptions.h" -# include "gromacs/utility/mutex.h" + /* none of the fftw3 calls, except execute(), are thread-safe, so we need to serialize them with this mutex. */ -static gmx::Mutex big_fftw_mutex; +static std::mutex big_fftw_mutex; # define FFTW_LOCK \ try \ { \ diff --git a/src/gromacs/fft/fft_fftw3.cpp b/src/gromacs/fft/fft_fftw3.cpp index 7e1f0e420c..6c704af93b 100644 --- a/src/gromacs/fft/fft_fftw3.cpp +++ b/src/gromacs/fft/fft_fftw3.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2003 David van der Spoel, Erik Lindahl, University of Groningen. * Copyright (c) 2013,2014,2015,2017,2018 by the GROMACS development team. - * Copyright (c) 2019,2020, by the GROMACS development team, led by + * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -41,12 +41,13 @@ #include #include +#include + #include #include "gromacs/fft/fft.h" #include "gromacs/utility/exceptions.h" #include "gromacs/utility/fatalerror.h" -#include "gromacs/utility/mutex.h" #if GMX_DOUBLE # define FFTWPREFIX(name) fftw_##name @@ -56,7 +57,7 @@ /* none of the fftw3 calls, except execute(), are thread-safe, so we need to serialize them with this mutex. */ -static gmx::Mutex big_fftw_mutex; +static std::mutex big_fftw_mutex; #define FFTW_LOCK \ try \ { \ diff --git a/src/gromacs/fileio/gmxfio.cpp b/src/gromacs/fileio/gmxfio.cpp index cad75e64eb..013b8472e5 100644 --- a/src/gromacs/fileio/gmxfio.cpp +++ b/src/gromacs/fileio/gmxfio.cpp @@ -4,7 +4,7 @@ * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. * Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team. - * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,6 +45,7 @@ #include #include +#include #include #if HAVE_IO_H @@ -60,7 +61,6 @@ #include "gromacs/fileio/md5.h" #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/futil.h" -#include "gromacs/utility/mutex.h" #include "gromacs/utility/smalloc.h" #include "gmxfio_impl.h" @@ -82,9 +82,9 @@ static t_fileio* open_files = nullptr; opening and closing of files, or during global operations like iterating along all open files. All these cases should be rare during the simulation. */ -static gmx::Mutex open_file_mutex; +static std::mutex open_file_mutex; -using Lock = gmx::lock_guard; +using Lock = std::lock_guard; /****************************************************************** * diff --git a/src/gromacs/fileio/timecontrol.cpp b/src/gromacs/fileio/timecontrol.cpp index fae0dd6b8d..fb3c2d050f 100644 --- a/src/gromacs/fileio/timecontrol.cpp +++ b/src/gromacs/fileio/timecontrol.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2018,2019,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -38,7 +38,7 @@ #include "timecontrol.h" -#include "thread_mpi/threads.h" +#include #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/fatalerror.h" @@ -56,16 +56,15 @@ typedef struct static t_timecontrol timecontrol[TNR] = { { 0, FALSE }, { 0, FALSE }, { 0, FALSE } }; -static tMPI_Thread_mutex_t tc_mutex = TMPI_THREAD_MUTEX_INITIALIZER; +static std::mutex g_timeControlMutex; gmx_bool bTimeSet(int tcontrol) { gmx_bool ret; - tMPI_Thread_mutex_lock(&tc_mutex); + const std::lock_guard lock(g_timeControlMutex); range_check(tcontrol, 0, TNR); ret = timecontrol[tcontrol].bSet; - tMPI_Thread_mutex_unlock(&tc_mutex); return ret; } @@ -74,18 +73,16 @@ real rTimeValue(int tcontrol) { real ret; - tMPI_Thread_mutex_lock(&tc_mutex); + const std::lock_guard lock(g_timeControlMutex); range_check(tcontrol, 0, TNR); ret = timecontrol[tcontrol].t; - tMPI_Thread_mutex_unlock(&tc_mutex); return ret; } void setTimeValue(int tcontrol, real value) { - tMPI_Thread_mutex_lock(&tc_mutex); + const std::lock_guard lock(g_timeControlMutex); range_check(tcontrol, 0, TNR); timecontrol[tcontrol].t = value; timecontrol[tcontrol].bSet = TRUE; - tMPI_Thread_mutex_unlock(&tc_mutex); } diff --git a/src/gromacs/gpu_utils/clfftinitializer.cpp b/src/gromacs/gpu_utils/clfftinitializer.cpp index 5097649d47..2734f2a9a2 100644 --- a/src/gromacs/gpu_utils/clfftinitializer.cpp +++ b/src/gromacs/gpu_utils/clfftinitializer.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,9 +45,10 @@ #include "config.h" +#include + #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/exceptions.h" -#include "gromacs/utility/mutex.h" #include "gromacs/utility/stringutil.h" #if GMX_GPU_OPENCL @@ -68,7 +69,7 @@ namespace * initialize it more than once. */ //! @{ bool g_clfftInitialized = false; -gmx::Mutex g_clfftMutex; +std::mutex g_clfftMutex; //! @} #endif @@ -77,7 +78,7 @@ gmx::Mutex g_clfftMutex; ClfftInitializer::ClfftInitializer() { #if GMX_GPU_OPENCL - gmx::lock_guard guard(g_clfftMutex); + std::lock_guard guard(g_clfftMutex); clfftSetupData fftSetup; int initErrorCode = clfftInitSetupData(&fftSetup); if (initErrorCode != 0) @@ -98,7 +99,7 @@ ClfftInitializer::ClfftInitializer() ClfftInitializer::~ClfftInitializer() { #if GMX_GPU_OPENCL - gmx::lock_guard guard(g_clfftMutex); + std::lock_guard guard(g_clfftMutex); if (g_clfftInitialized) { clfftTeardown(); diff --git a/src/gromacs/nbnxm/opencl/nbnxm_ocl.cpp b/src/gromacs/nbnxm/opencl/nbnxm_ocl.cpp index 2f6cb2db7b..165079bce4 100644 --- a/src/gromacs/nbnxm/opencl/nbnxm_ocl.cpp +++ b/src/gromacs/nbnxm/opencl/nbnxm_ocl.cpp @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team. - * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,8 +68,6 @@ # include #endif -#include "thread_mpi/atomic.h" - #include "gromacs/gpu_utils/device_context.h" #include "gromacs/gpu_utils/gputraits_ocl.h" #include "gromacs/gpu_utils/oclutils.h" diff --git a/src/gromacs/pulling/pull.cpp b/src/gromacs/pulling/pull.cpp index bb7bb49410..4140acb066 100644 --- a/src/gromacs/pulling/pull.cpp +++ b/src/gromacs/pulling/pull.cpp @@ -48,6 +48,7 @@ #include #include +#include #include "gromacs/commandline/filenm.h" #include "gromacs/domdec/domdec_struct.h" @@ -73,7 +74,6 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/futil.h" #include "gromacs/utility/gmxassert.h" -#include "gromacs/utility/mutex.h" #include "gromacs/utility/pleasecite.h" #include "gromacs/utility/real.h" #include "gromacs/utility/smalloc.h" @@ -1413,9 +1413,9 @@ static PullCoordVectorForces calculateVectorForces(const pull_coord_work_t& pcrd * We could use a different, local mutex for each pull object, but the overhead * is extremely small here and registration is only done during initialization. */ -static gmx::Mutex registrationMutex; +static std::mutex registrationMutex; -using Lock = gmx::lock_guard; +using Lock = std::lock_guard; void register_external_pull_potential(struct pull_t* pull, int coord_index, const char* provider) { diff --git a/src/gromacs/selection/nbsearch.cpp b/src/gromacs/selection/nbsearch.cpp index da36743f82..693b4e020e 100644 --- a/src/gromacs/selection/nbsearch.cpp +++ b/src/gromacs/selection/nbsearch.cpp @@ -59,6 +59,7 @@ #include #include +#include #include #include "gromacs/math/functions.h" @@ -69,7 +70,6 @@ #include "gromacs/utility/exceptions.h" #include "gromacs/utility/gmxassert.h" #include "gromacs/utility/listoflists.h" -#include "gromacs/utility/mutex.h" #include "gromacs/utility/stringutil.h" #include "position.h" @@ -321,7 +321,7 @@ private: //! Data structure to hold the grid cell contents. CellList cells_; - Mutex createPairSearchMutex_; + std::mutex createPairSearchMutex_; PairSearchList pairSearchList_; friend class AnalysisNeighborhoodPairSearchImpl; @@ -452,7 +452,7 @@ AnalysisNeighborhoodSearchImpl::~AnalysisNeighborhoodSearchImpl() AnalysisNeighborhoodSearchImpl::PairSearchImplPointer AnalysisNeighborhoodSearchImpl::getPairSearch() { - lock_guard lock(createPairSearchMutex_); + std::lock_guard lock(createPairSearchMutex_); // TODO: Consider whether this needs to/can be faster, e.g., by keeping a // separate pool of unused search objects. PairSearchList::const_iterator i; @@ -1255,7 +1255,7 @@ public: SearchImplPointer getSearch(); - Mutex createSearchMutex_; + std::mutex createSearchMutex_; SearchList searchList_; real cutoff_; const ListOfLists* excls_; @@ -1265,7 +1265,7 @@ public: AnalysisNeighborhood::Impl::SearchImplPointer AnalysisNeighborhood::Impl::getSearch() { - lock_guard lock(createSearchMutex_); + std::lock_guard lock(createSearchMutex_); // TODO: Consider whether this needs to/can be faster, e.g., by keeping a // separate pool of unused search objects. SearchList::const_iterator i; diff --git a/src/gromacs/utility/exceptions.cpp b/src/gromacs/utility/exceptions.cpp index 0bda422e35..c6fa123cad 100644 --- a/src/gromacs/utility/exceptions.cpp +++ b/src/gromacs/utility/exceptions.cpp @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 2011-2018, The GROMACS development team. - * Copyright (c) 2019,2020, by the GROMACS development team, led by + * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,8 +52,6 @@ #include #include -#include "thread_mpi/system_error.h" - #include "gromacs/utility/basenetwork.h" #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/gmxassert.h" @@ -509,10 +507,6 @@ void printFatalErrorMessage(FILE* fp, const std::exception& ex) { title = getErrorCodeString(gmxEx->errorCode()); } - else if (dynamic_cast(&ex) != nullptr) - { - title = "System error in thread synchronization"; - } else if (dynamic_cast(&ex) != nullptr) { title = "Memory allocation failed"; diff --git a/src/gromacs/utility/fatalerror.cpp b/src/gromacs/utility/fatalerror.cpp index 6d9a347b5b..fe6a77e315 100644 --- a/src/gromacs/utility/fatalerror.cpp +++ b/src/gromacs/utility/fatalerror.cpp @@ -4,7 +4,7 @@ * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. * Copyright (c) 2013,2014,2015,2016,2017, The GROMACS development team. - * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,12 +47,12 @@ #include #include +#include #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/baseversion.h" #include "gromacs/utility/cstringutil.h" #include "gromacs/utility/futil.h" -#include "gromacs/utility/mutex.h" #include "gromacs/utility/programcontext.h" #include "gromacs/utility/stringutil.h" @@ -71,9 +71,9 @@ FILE* debug = nullptr; gmx_bool gmx_debug_at = FALSE; static FILE* log_file = nullptr; -static gmx::Mutex error_mutex; +static std::mutex error_mutex; -using Lock = gmx::lock_guard; +using Lock = std::lock_guard; void gmx_init_debug(const int dbglevel, const char* dbgfile) { diff --git a/src/gromacs/utility/futil.cpp b/src/gromacs/utility/futil.cpp index 2399188036..d20e8e63ea 100644 --- a/src/gromacs/utility/futil.cpp +++ b/src/gromacs/utility/futil.cpp @@ -4,7 +4,7 @@ * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. * Copyright (c) 2013,2014,2015,2016,2017, The GROMACS development team. - * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,6 +46,7 @@ #include #include +#include #include #include @@ -66,7 +67,6 @@ #include "gromacs/utility/dir_separator.h" #include "gromacs/utility/exceptions.h" #include "gromacs/utility/fatalerror.h" -#include "gromacs/utility/mutex.h" #include "gromacs/utility/path.h" #include "gromacs/utility/programcontext.h" #include "gromacs/utility/smalloc.h" @@ -88,9 +88,9 @@ static int s_maxBackupCount = 0; /* this linked list is an intrinsically globally shared object, so we have to protect it with mutexes */ -static gmx::Mutex pstack_mutex; +static std::mutex pstack_mutex; -using Lock = gmx::lock_guard; +using Lock = std::lock_guard; namespace gmx { diff --git a/src/gromacs/utility/keyvaluetreeserializer.cpp b/src/gromacs/utility/keyvaluetreeserializer.cpp index 14510239cf..5cb8db913d 100644 --- a/src/gromacs/utility/keyvaluetreeserializer.cpp +++ b/src/gromacs/utility/keyvaluetreeserializer.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2018,2019,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -36,10 +36,11 @@ #include "keyvaluetreeserializer.h" +#include + #include "gromacs/utility/iserializer.h" #include "gromacs/utility/keyvaluetree.h" #include "gromacs/utility/keyvaluetreebuilder.h" -#include "gromacs/utility/mutex.h" namespace gmx { @@ -68,12 +69,12 @@ private: DeserializerFunction deserialize; }; - static Mutex s_initMutex; + static std::mutex s_initMutex; static std::map s_serializers; static std::map s_deserializers; }; -Mutex ValueSerializer::s_initMutex; +std::mutex ValueSerializer::s_initMutex; std::map ValueSerializer::s_serializers; std::map ValueSerializer::s_deserializers; @@ -230,7 +231,7 @@ void serializeValueType(const KeyValueTreeValue& value, ISerializer* serializer) // static void ValueSerializer::initSerializers() { - lock_guard lock(s_initMutex); + std::lock_guard lock(s_initMutex); if (!s_serializers.empty()) { return; diff --git a/src/gromacs/utility/mutex.h b/src/gromacs/utility/mutex.h deleted file mode 100644 index 34c7375f22..0000000000 --- a/src/gromacs/utility/mutex.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of the GROMACS molecular simulation package. - * - * Copyright (c) 2015, by the GROMACS development team, led by - * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, - * and including many others, as listed in the AUTHORS file in the - * top-level source directory and at http://www.gromacs.org. - * - * GROMACS is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * GROMACS is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with GROMACS; if not, see - * http://www.gnu.org/licenses, or write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * If you want to redistribute modifications to GROMACS, please - * consider that scientific software is very special. Version - * control is crucial - bugs must be traceable. We will be happy to - * consider code for inclusion in the official distribution, but - * derived work must not be called official GROMACS. Details are found - * in the README & COPYING files - if they are missing, get the - * official version at http://www.gromacs.org. - * - * To help us fund GROMACS development, we humbly ask that you cite - * the research papers on the package. Check out http://www.gromacs.org. - */ -/*! \libinternal \file - * \brief - * Declares C++11-style basic threading primitives - * (gmx::Mutex, gmx::lock_guard). - * - * For now, the implementation is imported from thread-MPI. - * - * \author Teemu Murtola - * \inlibraryapi - * \ingroup module_utility - */ -#ifndef GMX_THREADING_MUTEX_H -#define GMX_THREADING_MUTEX_H - -#include "thread_mpi/mutex.h" - -namespace gmx -{ - -//! \cond libapi -/*! \libinternal \brief - * C++11-compatible basic mutex. - */ -typedef tMPI::mutex Mutex; -//! \endcond -using tMPI::lock_guard; - -} // namespace gmx - -#endif diff --git a/src/gromacs/utility/smalloc.cpp b/src/gromacs/utility/smalloc.cpp index c0511c32dc..79bf1010a6 100644 --- a/src/gromacs/utility/smalloc.cpp +++ b/src/gromacs/utility/smalloc.cpp @@ -4,7 +4,7 @@ * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. * Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team. - * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,14 +45,14 @@ #include #include +#include + #ifdef WITH_DMALLOC # include #endif #include -#include "thread_mpi/threads.h" - #include "gromacs/utility/alignedallocator.h" #include "gromacs/utility/dir_separator.h" #include "gromacs/utility/fatalerror.h" @@ -61,8 +61,8 @@ # include "gromacs/utility/gmxmpi.h" #endif -static gmx_bool g_bOverAllocDD = FALSE; -static tMPI_Thread_mutex_t g_over_alloc_mutex = TMPI_THREAD_MUTEX_INITIALIZER; +static bool g_bOverAllocDD = false; +static std::mutex g_overAllocMutex; void* save_malloc(const char* name, const char* file, int line, size_t size) { @@ -298,13 +298,12 @@ void save_free_aligned(const char gmx_unused* name, const char gmx_unused* file, gmx::AlignedAllocationPolicy::free(ptr); } -void set_over_alloc_dd(gmx_bool set) +void set_over_alloc_dd(bool set) { - tMPI_Thread_mutex_lock(&g_over_alloc_mutex); + std::lock_guard lock(g_overAllocMutex); /* we just make sure that we don't set this at the same time. We don't worry too much about reading this rarely-set variable */ g_bOverAllocDD = set; - tMPI_Thread_mutex_unlock(&g_over_alloc_mutex); } int over_alloc_dd(int n) diff --git a/src/gromacs/utility/smalloc.h b/src/gromacs/utility/smalloc.h index f68de025d3..bcac9adad5 100644 --- a/src/gromacs/utility/smalloc.h +++ b/src/gromacs/utility/smalloc.h @@ -3,7 +3,8 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2018,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2018,2019,2020, by the GROMACS development team. + * Copyright (c) 2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -357,7 +358,7 @@ constexpr float OVER_ALLOC_FAC = 1.19F; * This is mdrun-specific, so it might be better to put this and * over_alloc_dd() much higher up. */ -void set_over_alloc_dd(gmx_bool set); +void set_over_alloc_dd(bool set); /*! \brief * Returns new allocation count for domain decomposition allocations. diff --git a/src/gromacs/utility/tests/CMakeLists.txt b/src/gromacs/utility/tests/CMakeLists.txt index 6c9f47a028..88506a393a 100644 --- a/src/gromacs/utility/tests/CMakeLists.txt +++ b/src/gromacs/utility/tests/CMakeLists.txt @@ -2,7 +2,7 @@ # This file is part of the GROMACS molecular simulation package. # # Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team. -# Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by +# Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by # Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, # and including many others, as listed in the AUTHORS file in the # top-level source directory and at http://www.gromacs.org. @@ -48,7 +48,6 @@ gmx_add_unit_test(UtilityUnitTests utility-test listoflists.cpp logger.cpp mdmodulenotification-impl.cpp - mutex.cpp path.cpp physicalnodecommunicator.cpp range.cpp diff --git a/src/gromacs/utility/tests/mutex.cpp b/src/gromacs/utility/tests/mutex.cpp deleted file mode 100644 index dba7019add..0000000000 --- a/src/gromacs/utility/tests/mutex.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/* - * This file is part of the GROMACS molecular simulation package. - * - * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by - * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, - * and including many others, as listed in the AUTHORS file in the - * top-level source directory and at http://www.gromacs.org. - * - * GROMACS is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * GROMACS is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with GROMACS; if not, see - * http://www.gnu.org/licenses, or write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * If you want to redistribute modifications to GROMACS, please - * consider that scientific software is very special. Version - * control is crucial - bugs must be traceable. We will be happy to - * consider code for inclusion in the official distribution, but - * derived work must not be called official GROMACS. Details are found - * in the README & COPYING files - if they are missing, get the - * official version at http://www.gromacs.org. - * - * To help us fund GROMACS development, we humbly ask that you cite - * the research papers on the package. Check out http://www.gromacs.org. - */ -/*! \internal \file - * \brief Tests for gmx::Mutex - * - * These tests ensure that basic mutual-exclusion properties hold. - * Note that no testing can prove there isn't a bug, but if one - * exists, then these tests might expose one. - * - * In particular, try_lock can be implemented differently on different - * platforms, or with different default mutex types, so we should - * check that the behaviour continues to conform with the thread-MPI - * documentation. - * - * \author Mark Abraham - * \ingroup module_utility - */ - -#include "gmxpre.h" - -#include "gromacs/utility/mutex.h" - -#include "config.h" - -#include - -#include - - -namespace gmx -{ -namespace test -{ -namespace -{ - -//! Convenience definition. -using Lock = gmx::lock_guard; - -TEST(MutexBasicTest, CanBeMade) -{ - Mutex m; -} - -TEST(MutexBasicTest, CanBeLocked) -{ - Mutex m; - ASSERT_NO_THROW(m.lock()); - m.unlock(); -} - -TEST(MutexBasicTest, CanBeTryLocked) -{ - Mutex m; - ASSERT_TRUE(m.try_lock()); - m.unlock(); -} - -TEST(MutexBasicTest, CanBeUsedInLockGuard) -{ - Mutex m; - Lock g(m); -} - -//! A shared value for a mutex to protect -int g_sharedValue; -//! A mutex to protect a shared value -Mutex g_sharedValueMutex; - -//! Function type for asynchronous tasks. -using TaskType = std::function; - -//! A task that just does work. -int updateSharedValue() -{ - return ++g_sharedValue; -} - -//! A task that does work after it gets the mutex. -int updateSharedValueWithLock() -{ - Lock guard(g_sharedValueMutex); - return updateSharedValue(); -} - -//! A task that does work only if it can get the mutex immediately. -int updateSharedValueWithTryLock() -{ - // Special return value to signal when work was not done because - // the lock was not acquired. - int result = -1; - if (g_sharedValueMutex.try_lock()) - { - result = updateSharedValue(); - g_sharedValueMutex.unlock(); - } - return result; -} - -/*! \brief Parameterized test fixture. - * - * Checks that different launch policies work. In further tests of - * mutual exclusion, we need to specify std::thread::async, to require - * that a thread actually launched. The default policy permits the - * std:: implementation to avoid launching a thread, and at least the - * behaviour of thread-MPI try_lock also varies with the threading - * implementation underlying it. */ -class DifferentTasksTest : public ::testing::TestWithParam -{ -public: - DifferentTasksTest() { g_sharedValue = 0; } - //! Check the results - void checkResults() - { - int result = 0; - EXPECT_NO_THROW(result = futureResult_.get()) << "Future should not contain an exception"; - EXPECT_EQ(1, result) << "Task should have run"; - EXPECT_EQ(1, g_sharedValue) << "Shared value should be updated"; - } - //! Contains the result the task returns. - std::future futureResult_; -}; - -TEST_P(DifferentTasksTest, StdAsyncWorksWithDefaultPolicy) -{ - auto task = GetParam(); - EXPECT_NO_THROW(futureResult_ = std::async(task)) << "Async should succeed"; - checkResults(); -} - -TEST_P(DifferentTasksTest, StdAsyncWorksWithAsyncLaunchPolicy) -{ - auto task = GetParam(); - EXPECT_NO_THROW(futureResult_ = std::async(std::launch::async, task)) << "Async should succeed"; - checkResults(); -} - -TEST_P(DifferentTasksTest, StdAsyncWorksWithDeferredLaunchPolicy) -{ - auto task = GetParam(); - EXPECT_NO_THROW(futureResult_ = std::async(std::launch::deferred, task)) - << "Async should succeed"; - checkResults(); -} - -// Test that the different launch policies work with the different tasks -INSTANTIATE_TEST_CASE_P(WithAndWithoutMutex, - DifferentTasksTest, - ::testing::Values(updateSharedValue, - updateSharedValueWithLock, - updateSharedValueWithTryLock)); - -TEST(MutexTaskTest, MutualExclusionWorksWithLock) -{ - g_sharedValue = 0; - std::future result; - { - // Hold the mutex, launch a lock attempt on another - // thread, check that the shared value isn't changed, then - // release the mutex by leaving the scope, after which the - // other thread's lock can get the mutex. - Lock guard(g_sharedValueMutex); - result = std::async(std::launch::async, updateSharedValueWithLock); - EXPECT_EQ(0, g_sharedValue) << "Task should not have run yet"; - } - EXPECT_EQ(1, result.get()) << "Task should have run"; - EXPECT_EQ(1, g_sharedValue) << "Shared value should be updated"; -} - -TEST(MutexTaskTest, MutualExclusionWorksWithTryLockOnOtherThread) -{ - g_sharedValue = 0; - { - // Hold the mutex, launch a try_lock attempt on another - // thread, check that the shared value isn't changed, then - // make sure the try_lock attempt has returned, double check - // that the shared value isn't changed, and release the mutex - // by leaving the scope. - Lock guard(g_sharedValueMutex); - auto result = std::async(std::launch::async, updateSharedValueWithTryLock); - EXPECT_EQ(0, g_sharedValue) << "Data race detected"; - EXPECT_EQ(-1, result.get()) << "The try_lock should fail"; - EXPECT_EQ(0, g_sharedValue) << "Task should not have run"; - } - EXPECT_EQ(0, g_sharedValue) << "Mutex release can't affect the protected value"; -} - -TEST(MutexTaskTest, MutualExclusionWorksWithTryLockOnSameThread) -{ - g_sharedValue = 0; - int finalSharedValue = GMX_NATIVE_WINDOWS ? 1 : 0; - { - // Hold the mutex and launch a try_lock attempt on this - // thread. Behaviour then varies with the implementation - // underlying thread-MPI. - Lock guard(g_sharedValueMutex); - int result = updateSharedValueWithTryLock(); - if (GMX_NATIVE_WINDOWS) - { - EXPECT_EQ(1, result) << "The try_lock should succeed"; - EXPECT_EQ(finalSharedValue, g_sharedValue) << "Task should have run"; - } - else - { - EXPECT_EQ(-1, result) << "The try_lock should fail"; - EXPECT_EQ(finalSharedValue, g_sharedValue) << "Task should not have run"; - } - } - EXPECT_EQ(finalSharedValue, g_sharedValue) << "Mutex release can't affect the protected value"; -} - -} // namespace -} // namespace test -} // namespace gmx diff --git a/src/testutils/include/testutils/testoptions.h b/src/testutils/include/testutils/testoptions.h index 6b71215731..c3421ffff8 100644 --- a/src/testutils/include/testutils/testoptions.h +++ b/src/testutils/include/testutils/testoptions.h @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 2012,2013,2014,2015,2018 by the GROMACS development team. - * Copyright (c) 2019,2020, by the GROMACS development team, led by + * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -85,7 +85,6 @@ protected: * \param[in] name Name of the options provider (for ordering). * \param[in] provider The provider to register. * \throws std::bad_alloc if out of memory. - * \throws tMPI::system_error on mutex failures. * * Typically not used directly in test code, but through the * #GMX_TEST_OPTIONS macro. diff --git a/src/testutils/testoptions.cpp b/src/testutils/testoptions.cpp index 9e5b47f5dc..d3ecf41ebc 100644 --- a/src/testutils/testoptions.cpp +++ b/src/testutils/testoptions.cpp @@ -44,10 +44,10 @@ #include "testutils/testoptions.h" #include +#include #include #include "gromacs/utility/classhelpers.h" -#include "gromacs/utility/mutex.h" namespace gmx { @@ -75,7 +75,7 @@ public: //! Adds a provider into the registry. void add(const char* /*name*/, TestOptionsProvider* provider) { - lock_guard lock(listMutex_); + std::lock_guard lock(listMutex_); providerList_.push_back(provider); } @@ -87,7 +87,7 @@ private: typedef std::list ProviderList; - Mutex listMutex_; + std::mutex listMutex_; ProviderList providerList_; GMX_DISALLOW_COPY_AND_ASSIGN(TestOptionsRegistry); @@ -97,7 +97,7 @@ void TestOptionsRegistry::initOptions(IOptionsContainer* options) { // TODO: Have some deterministic order for the options; now it depends on // the order in which the global initializers are run. - lock_guard lock(listMutex_); + std::lock_guard lock(listMutex_); ProviderList::const_iterator i; for (i = providerList_.begin(); i != providerList_.end(); ++i) { -- 2.22.0