thread_mpi C++11 compatible mutex classes
authorSander Pronk <pronk@cbr.su.se>
Thu, 31 May 2012 09:58:21 +0000 (11:58 +0200)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Sat, 2 Jun 2012 05:44:39 +0000 (07:44 +0200)
This brings the master branch thread_mpi up to date, and introduces
a C++11 compatible API for mutexes and lock_guards (found in
thread_mpi/mutex.h).

Partially fixes http://redmine.gromacs.org/issues/948

Change-Id: Ibce48ae10e84bedee9fe641b94a21f6674efcd6b

21 files changed:
CMakeLists.txt
cmake/ThreadMPI.cmake
src/gromacs/gmxlib/CMakeLists.txt
src/gromacs/gmxlib/thread_mpi/CMakeLists.txt
src/gromacs/gmxlib/thread_mpi/impl.h
src/gromacs/gmxlib/thread_mpi/p2p_send_recv.c
src/gromacs/gmxlib/thread_mpi/system_error.cpp [new file with mode: 0644]
src/gromacs/legacyheaders/thread_mpi/atomic.h
src/gromacs/legacyheaders/thread_mpi/atomic/gcc_x86.h
src/gromacs/legacyheaders/thread_mpi/barrier.h
src/gromacs/legacyheaders/thread_mpi/collective.h
src/gromacs/legacyheaders/thread_mpi/event.h
src/gromacs/legacyheaders/thread_mpi/list.h
src/gromacs/legacyheaders/thread_mpi/lock.h
src/gromacs/legacyheaders/thread_mpi/mpi_bindings.h
src/gromacs/legacyheaders/thread_mpi/mutex.h [new file with mode: 0644]
src/gromacs/legacyheaders/thread_mpi/numa_malloc.h
src/gromacs/legacyheaders/thread_mpi/system_error.h [new file with mode: 0644]
src/gromacs/legacyheaders/thread_mpi/threads.h
src/gromacs/legacyheaders/thread_mpi/tmpi.h
src/gromacs/legacyheaders/thread_mpi/wait.h

index 67cb4591852a68080533eb280a34c0e92b7eeb57..ba9d85e15602a7fc41b58bf5340ed79e0366c791 100644 (file)
@@ -377,6 +377,7 @@ endif(GMX_X11)
 if(GMX_THREAD_MPI)
     set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_THREAD_MPI")
     include(ThreadMPI)
+    tmpi_make_cxx_lib()
     set(THREAD_MPI_LIB thread_mpi)
     set(GMX_MPI 1)
     string(TOUPPER ${GMX_FFT_LIBRARY} ${GMX_FFT_LIBRARY})
index 9bcd978b73803dcb5ebbe257a05f81da23020c5c..a5b2e7b6e30f9b34214606e8c89775f95f1a1cb6 100644 (file)
@@ -21,6 +21,12 @@ MACRO(TEST_TMPI_ATOMICS VARIABLE)
     endif(NOT DEFINED TMPI_ATOMICS)
 ENDMACRO(TEST_TMPI_ATOMICS VARIABLE)
 
+MACRO(TMPI_MAKE_CXX_LIB)
+    set(TMPI_CXX_LIB 1)
+    # the C++ library
+    set(THREAD_MPI_CXX_SRC
+        thread_mpi/system_error.cpp )
+ENDMACRO(TMPI_MAKE_CXX_LIB)
 
 include(FindThreads)
 if (CMAKE_USE_PTHREADS_INIT)
@@ -39,7 +45,7 @@ if (CMAKE_USE_PTHREADS_INIT)
         thread_mpi/group.c         thread_mpi/tmpi_init.c
         thread_mpi/topology.c      thread_mpi/list.c          
         thread_mpi/type.c          thread_mpi/lock.c
-        thread_mpi/numa_malloc.c   thread_mpi/once.c)
+        thread_mpi/numa_malloc.c   thread_mpi/once.c )
     set(THREAD_LIB ${CMAKE_THREAD_LIBS_INIT})
 else (CMAKE_USE_PTHREADS_INIT)
     if (CMAKE_USE_WIN32_THREADS_INIT)
@@ -63,6 +69,7 @@ else (CMAKE_USE_PTHREADS_INIT)
     endif (CMAKE_USE_WIN32_THREADS_INIT)
 endif (CMAKE_USE_PTHREADS_INIT)
 
+
 # the spin-waiting option
 option(THREAD_MPI_WAIT_FOR_NO_ONE "Use busy waits without yielding to the OS scheduler. Turning this on might improve performance (very) slightly at the cost of very poor performance if the threads are competing for CPU time." OFF)
 mark_as_advanced(THREAD_MPI_WAIT_FOR_NO_ONE)
@@ -94,6 +101,18 @@ endif (THREAD_MPI_PROFILING)
 
 include(CheckCSourceCompiles)
 
+## Windows NUMA allocator
+#if (THREAD_WINDOWS)
+#      check_c_source_compiles(
+#      "#include <windows.h>
+#      int main(void) { PROCESSOR_NUMBER a; return 0; }"
+#      HAVE_PROCESSOR_NUMBER)
+#      if(HAVE_PROCESSOR_NUMBER)
+#            #add_definitions(-DTMPI_WINDOWS_NUMA_API)
+#            set(TMPI_WINDOWS_NUMA_API 1)
+#      endif(HAVE_PROCESSOR_NUMBER)
+#endif(THREAD_WINDOWS)
+
 # option to set affinity 
 option(THREAD_MPI_SET_AFFINITY "Set thread affinity to a core if number of threads equal to number of hardware threads." ON)
 mark_as_advanced(THREAD_MPI_SET_AFFINITY)
index e0ba1459618686b5c2b4d98fd1f235c7bb990f8f..c84de7ca5e79d901a0c7a58c943366ed7baaeb3a 100644 (file)
@@ -70,9 +70,11 @@ endif()
 
 # An ugly hack to get absolute paths...
 file(GLOB THREAD_MPI_SOURCES ${THREAD_MPI_SRC})
+file(GLOB THREAD_MPI_CXX_SOURCES ${THREAD_MPI_CXX_SRC})
 
 set(GMX_SSEKERNEL_ASM_SRC ${GMX_SSEKERNEL_ASM_SRC} PARENT_SCOPE)
 set(GMXLIB_SOURCES ${GMXLIB_SOURCES}
     ${GMX_SSEKERNEL_C_SRC} ${FORTRAN_SOURCES}
     ${GMX_BLUEGENE_C_SRC} ${GMX_PPC_ALTIVEC_SRC} ${THREAD_MPI_SOURCES}
+    ${THREAD_MPI_CXX_SOURCES}
     PARENT_SCOPE)
index 5aba9ed8410fcb2795c55eea73d2162b2868c5fe..0eefecb5f392a8e498ad069869627ed909198286 100644 (file)
@@ -10,7 +10,7 @@ set(THREAD_MPI_LIB_SOURCE
     errhandler.c    p2p_send_recv.c type.c
     event.c         p2p_wait.c      
     gather.c        profile.c
-    group.c         numa_malloc.c)
+    group.c         numa_malloc.c   )
 
 
 if (THREAD_PTHREADS)
@@ -27,6 +27,12 @@ add_library(thread_mpi STATIC ${THREAD_MPI_LIB_SOURCE})
 # make it link to the threads library (-lpthreads, for example)
 target_link_libraries(thread_mpi ${THREAD_LIB})
 
+if (TMPI_CXX_LIB)
+    set(THREAD_MPI_CXX_LIB_SOURCE 
+        system_error.cpp )
+    add_library(thread_mpi_cxx STATIC ${THREAD_MPI_CXX_LIB_SOURCE})
+    target_link_libraries(thread_mpi_cxx thread_mpi)
+endif (TMPI_CXX_LIB)
 
 #configure_file(tmpi_config.h.cmakein  tmpi_config.h)
 #add_definitions(-DHAVE_TMPI_CONFIG_H)
@@ -39,3 +45,4 @@ configure_file(tmpi_config.h.cmakein  ${CMAKE_CURRENT_BINARY_DIR}/tmpi_config.h)
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
 add_definitions(-DHAVE_TMPI_CONFIG_H)
 
+install(TARGETS thread_mpi DESTINATION lib)
index 5fd105c4be996ad19f97e93b2fd1bd841f141f72..cb39f26a86135b9297d769eac9665b33510a33dc 100644 (file)
@@ -415,7 +415,7 @@ struct tmpi_thread
     /* the p2p communication events (incoming envelopes + finished send 
        envelopes generate events) */
     tMPI_Event p2p_event;
-    TMPI_YIELD_WAIT_DATA; /* data associated with waiting */
+    TMPI_YIELD_WAIT_DATA /* data associated with waiting */
     struct req_list rql;  /* list of pre-allocated requests */
 
     /* collective communication structures: */
index 3f1f5aa2da8ea9f365d7ba33a28b8abce51f9033..b106a70f94a40f07328c29914d7789f3508ef12a 100644 (file)
@@ -80,7 +80,7 @@ int tMPI_Send(void* buf, int count, tMPI_Datatype datatype, int dest,
     {
         return tMPI_Error(TMPI_COMM_WORLD, TMPI_ERR_COMM);
     }
-    send_dst = tMPI_Get_thread(comm, dest);
+    send_dst=tMPI_Get_thread(comm, dest);
     if (!send_dst)
     {
         return tMPI_Error(comm, TMPI_ERR_SEND_DEST);
diff --git a/src/gromacs/gmxlib/thread_mpi/system_error.cpp b/src/gromacs/gmxlib/thread_mpi/system_error.cpp
new file mode 100644 (file)
index 0000000..8ae7d55
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+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.
+*/
+
+#ifdef __cplusplus
+
+#include <cerrno>
+#include <cstring>
+#include <cstdlib>
+#include <stdexcept>
+#include "thread_mpi/system_error.h"
+
+tMPI::system_error::system_error(error_code ec) 
+    : runtime_error(std::strerror(ec)), ec_(ec)
+{
+}
+
+#endif /* __cplusplus */
+
index 6133286bab7317036575c8c3870e9323a534ea53..dd28bf7ea171cbd86415fce3fc32a6139c1843de 100644 (file)
@@ -35,8 +35,8 @@ be called official thread_mpi. Details are found in the README & COPYING
 files.
 */
 
-#ifndef _TMPI_ATOMIC_H_
-#define _TMPI_ATOMIC_H_
+#ifndef TMPI_ATOMIC_H_
+#define TMPI_ATOMIC_H_
 
 /*! \file atomic.h
  *
@@ -96,8 +96,11 @@ extern "C"
    too */
 #if ( (defined(__GNUC__) || defined(__PATHSCALE__) || defined(__PGI)) && (!defined(__xlc__)) )
 
+
+
+
 /* now check specifically for several architectures: */
-#if (defined(i386) || defined(__x86_64__)) 
+#if ((defined(i386) || defined(__x86_64__)) && ! defined(__OPEN64__))
 /* first x86: */
 #include "atomic/gcc_x86.h"
 /*#include "atomic/gcc.h"*/
@@ -690,4 +693,4 @@ static inline void *tMPI_Atomic_ptr_swap(tMPI_Atomic_ptr_t *a, void *b)
 #endif
 
 
-#endif /* _TMPI_ATOMIC_H_ */
+#endif /* TMPI_ATOMIC_H_ */
index 0c388e7b4af99be397bbc83d2bc636f1f9343fe0..e5415afea9cfb98cb831cff4825b25c90b64f48a 100644 (file)
@@ -57,22 +57,23 @@ files.
 
 /* we put all of these on their own cache line by padding the data structure
    to the size of a cache line on x86 (64 bytes): */
+#define TMPI_SIZEOF_X86_CACHE_LINE 64
 typedef struct tMPI_Atomic
 {
     int value; 
-    char padding[64-sizeof(int)];
+    char padding[TMPI_SIZEOF_X86_CACHE_LINE-sizeof(int)];
 } tMPI_Atomic_t;
 
 typedef struct tMPI_Atomic_ptr
 {
     void* value; 
-    char padding[64-sizeof(void*)];
+    char padding[TMPI_SIZEOF_X86_CACHE_LINE-sizeof(void*)];
 } tMPI_Atomic_ptr_t;
 
 typedef struct tMPI_Spinlock
 {
     unsigned int lock; 
-    char padding[64-sizeof(unsigned int)];
+    char padding[TMPI_SIZEOF_X86_CACHE_LINE-sizeof(unsigned int)];
 } tMPI_Spinlock_t;
 
 
index 08b4773476209d547d2a8702103b90d51cb317d0..a531878ac7a401f31d088f1cfd267ceb4607a3f2 100644 (file)
@@ -35,8 +35,8 @@ be called official thread_mpi. Details are found in the README & COPYING
 files.
 */
 
-#ifndef _TMPI_BARRIER_H_
-#define _TMPI_BARRIER_H_
+#ifndef TMPI_BARRIER_H_
+#define TMPI_BARRIER_H_
 
 #include "wait.h"
 
@@ -63,7 +63,7 @@ struct tMPI_Barrier_t
     tMPI_Atomic_t     count;     /*!< Number of threads remaining     */
     int               threshold; /*!< Total number of threads         */
     volatile int      cycle;     /*!< Current cycle (alternating 0/1) */
-    TMPI_YIELD_WAIT_DATA;
+    TMPI_YIELD_WAIT_DATA
 };
 
 
@@ -108,4 +108,4 @@ int tMPI_Barrier_N(tMPI_Barrier_t *barrier);
 #define tMPI_Barrier_N(barrier)  ((barrier)->threshold)
 #endif
 
-#endif
+#endif /* TMPI_BARRIER_H_ */
index ec13f76c2ae5b5a69b6f053ab4ae09fa3369785a..11bc52ce692716fe81e87d9df2b4618db920f0df 100644 (file)
@@ -35,8 +35,8 @@ be called official thread_mpi. Details are found in the README & COPYING
 files.
 */
 
-#ifndef _THREAD_MPI_COLLECTIVE_H_
-#define _THREAD_MPI_COLLECTIVE_H_
+#ifndef TMPI_COLLECTIVE_H_
+#define TMPI_COLLECTIVE_H_
 
 /** \file 
  *
@@ -146,4 +146,4 @@ void tMPI_Reduce_wait_results(tMPI_Reduce_req *req, void *res);
 } /* closing extern "C" */
 #endif
 
-#endif /* _THREAD_MPI_COLLECTIVE_H_ */
+#endif /* TMPI_COLLECTIVE_H_ */
index fcf413e2b76dc26553eb36836c1670499858de17..a8faa85cbefc88cd76242b2b5e871e3256f21311 100644 (file)
@@ -35,8 +35,8 @@ be called official thread_mpi. Details are found in the README & COPYING
 files.
 */
 
-#ifndef _TMPI_EVENT_H_
-#define _TMPI_EVENT_H_
+#ifndef TMPI_EVENT_H_
+#define TMPI_EVENT_H_
 
 #include "wait.h"
 
@@ -66,7 +66,7 @@ struct tMPI_Event_t
 {
     tMPI_Atomic_t sync; /* the event sync counter */
     int last_sync; /* the last sync event looked at */
-    TMPI_YIELD_WAIT_DATA;   /* data associated with yielding */
+    TMPI_YIELD_WAIT_DATA   /* data associated with yielding */
 };
 
 
@@ -119,5 +119,5 @@ void tMPI_Event_process(tMPI_Event *ev, int N);
 }
 #endif
 
-#endif
+#endif /* TMPI_EVENT_H_ */
 
index 779b770cb66a7e15ef5c0567f5cf80b45fde5f2f..a27247805315d395b43dc551e3f6be39eb16a086 100644 (file)
@@ -35,8 +35,8 @@ be called official thread_mpi. Details are found in the README & COPYING
 files.
 */
 
-#ifndef _TMPI_LIST_H_
-#define _TMPI_LIST_H_
+#ifndef TMPI_LIST_H_
+#define TMPI_LIST_H_
 
 #include "atomic.h"
 
@@ -155,4 +155,4 @@ void tMPI_List_remove(tMPI_List *l, tMPI_List_element *le);
 } /* closing extern "C" */
 #endif
 
-#endif /* _TMPI_H_ */
+#endif /* TMPI_LIST_H_ */
index e8144dba94284303a09fd9bac6b97e886e1b5885..65e65aa45399fa53145e3d7e4b094e63f86efa48 100644 (file)
@@ -35,8 +35,8 @@ be called official thread_mpi. Details are found in the README & COPYING
 files.
 */
 
-#ifndef _TMPI_FASTLOCK_H_
-#define _TMPI_FASTLOCK_H_
+#ifndef TMPI_FASTLOCK_H_
+#define TMPI_FASTLOCK_H_
 
 #include "wait.h"
 #include "atomic.h"
@@ -59,7 +59,7 @@ typedef struct tMPI_Lock tMPI_Lock_t;
 struct tMPI_Lock
 {
     tMPI_Spinlock_t   lock;      /*!< The underlying spin lock */
-    TMPI_YIELD_WAIT_DATA;
+    TMPI_YIELD_WAIT_DATA
 };
 
 
@@ -98,4 +98,4 @@ int tMPI_Lock_islocked(const tMPI_Lock_t *lock);
 
 
 
-#endif
+#endif /* TMPI_FASTLOCK_H_ */
index 40153f8ad2bc972fe436e17c7e58362e4a7d301f..197028f50e892192b945981e3de8910df6bc31a7 100644 (file)
@@ -35,8 +35,8 @@ be called official thread_mpi. Details are found in the README & COPYING
 files.
 */
 
-#ifndef _MPI_BINDINGS_H_
-#define _MPI_BINDINGS_H_
+#ifndef TMPI_MPI_BINDINGS_H_
+#define TMPI_MPI_BINDINGS_H_
 
 /** \file
   \brief MPI bindings for thread_mpi/tmpi.h
@@ -257,5 +257,5 @@ typedef struct tmpi_datatype_ *MPI_Datatype;
 
 #endif
 
-#endif /* _MPI_BINDINGS_H_ */
+#endif /* TMPI_MPI_BINDINGS_H_ */
 
diff --git a/src/gromacs/legacyheaders/thread_mpi/mutex.h b/src/gromacs/legacyheaders/thread_mpi/mutex.h
new file mode 100644 (file)
index 0000000..f657a11
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+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 "system_error.h"
+#include "threads.h"
+
+#ifdef __cplusplus
+
+
+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<tMPI::mutex> lock(mtx);
+            count += 1;
+        }
+    */
+    template <class Mutex> class lock_guard 
+    {
+    public:
+        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 mutex
+    {
+    public:
+        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.
+
+        Throws a tMPI::system_error exception upon failure. 
+        \return true if the lock was locked successfully, false if not*/
+        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);
+        }
+
+        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 /* __cplusplus */
+
+#endif  /* TMPI_MUTEX_H_ */
+
index 29a0a167d845f4d5355d1b6324b6c081b12eab04..526392e4a87c10d28e25c43df8dd146230ee2113 100644 (file)
@@ -36,8 +36,8 @@ files.
 */
 
 
-#ifndef _TMPI_NUMA_MALLOC_H_
-#define _TMPI_NUMA_MALLOC_H_
+#ifndef TMPI_NUMA_MALLOC_H_
+#define TMPI_NUMA_MALLOC_H_
 
 /*! \file numa_alloc.h
   
@@ -126,5 +126,5 @@ int tMPI_Free_numa(void *ptr);
 }
 #endif
 
-#endif /* _TMPI_NUMA_MALLOC_H_ */
+#endif /* TMPI_NUMA_MALLOC_H_ */
 
diff --git a/src/gromacs/legacyheaders/thread_mpi/system_error.h b/src/gromacs/legacyheaders/thread_mpi/system_error.h
new file mode 100644 (file)
index 0000000..f00f28c
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+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 <stdexcept>
+
+#ifdef __cplusplus
+
+
+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:
+        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 */
+        system_error(error_code ec) ;
+
+        /*! \brief Returns the error code */
+        const error_code& code() const 
+        {
+            return ec_;
+        }
+    private:
+        error_code ec_;
+    };
+}
+
+#endif /* __cplusplus */
+
+#endif  /* TMPI_SYSTEM_ERROR_H_ */
index d8dfe707c0257a163f16e1078dfea429b176121a..cd401698f3d355917131cac1df7b1bf3acbe16bb 100644 (file)
@@ -36,8 +36,8 @@ files.
 */
 
 
-#ifndef _TMPI_THREAD_H_
-#define _TMPI_THREAD_H_
+#ifndef TMPI_THREADS_H_
+#define TMPI_THREADS_H_
 
 /*! \file threads.h
  *
@@ -367,10 +367,10 @@ int tMPI_Thread_mutex_lock(tMPI_Thread_mutex_t *mtx);
  *
  *  This routine always return directly. If the mutex was available and
  *  we successfully locked it we return 0, otherwise a non-zero
- *  error code (usually meaning the mutex was already locked).
+ *  return code (usually meaning the mutex was already locked).
  *
  *  \param mtx  Pointer to the mutex to try and lock
- *  \return 0 or a non-zero error code.
+ *  \return 0 or a non-zero return error code.
  */
 int tMPI_Thread_mutex_trylock(tMPI_Thread_mutex_t *mtx);
 
@@ -600,5 +600,5 @@ int tMPI_Thread_barrier_wait(tMPI_Thread_barrier_t *barrier);
 }
 #endif
 
-#endif /* _TMPI_THREAD_H_ */
+#endif /* TMPI_THREADS_H_ */
 
index 4a652e7f05cd730687720c8c39344eb06141ca5b..c8fb3e174c9d80f6bc1af8d79d08915cccd4569a 100644 (file)
@@ -35,8 +35,8 @@ be called official thread_mpi. Details are found in the README & COPYING
 files.
 */
 
-#ifndef _TMPI_H_
-#define _TMPI_H_
+#ifndef TMPI_TMPI_H_
+#define TMPI_TMPI_H_
 
 /** \file 
  *
@@ -1244,4 +1244,4 @@ int tMPI_Reduce_fast(void* sendbuf, void* recvbuf, int count,
 } /* closing extern "C" */
 #endif
 
-#endif /* _TMPI_H_ */
+#endif /* TMPI_TMPI_H_ */
index ba0350705c71c33e9a2435a0ea760af1503e99e2..41b8fa426d4ad51c3662f16a25b9a088485b6435 100644 (file)
@@ -36,8 +36,8 @@ files.
 */
 
 
-#ifndef _TMPI_WAIT_H_
-#define _TMPI_WAIT_H_
+#ifndef TMPI_WAIT_H_
+#define TMPI_WAIT_H_
 
 #ifndef TMPI_WAIT_FOR_NO_ONE
 
@@ -65,7 +65,7 @@ files.
    lead to starvation. This mixed approach actually gives better real-world 
    performance in the test program.*/
 /* the data associated with waiting. */
-#define TMPI_YIELD_WAIT_DATA  int yield_wait_counter
+#define TMPI_YIELD_WAIT_DATA  int yield_wait_counter;
 /* the initialization  associated with waiting. */
 #define TMPI_YIELD_WAIT_DATA_INIT(data) { (data)->yield_wait_counter=0; }
 
@@ -97,5 +97,5 @@ files.
 
 #endif /* !TMPI_WAIT_FOR_NO_ONE */
 
-#endif
+#endif /* TMPI_WAIT_H_ */