|
phdMesh Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* TPI: Thread Pool Interface */ 00003 /* Copyright (2008) Sandia Corporation */ 00004 /* */ 00005 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */ 00006 /* license for use of this work by or on behalf of the U.S. Government. */ 00007 /* */ 00008 /* This library is free software; you can redistribute it and/or modify */ 00009 /* it under the terms of the GNU Lesser General Public License as */ 00010 /* published by the Free Software Foundation; either version 2.1 of the */ 00011 /* License, or (at your option) any later version. */ 00012 /* */ 00013 /* This library is distributed in the hope that it will be useful, */ 00014 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 00015 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */ 00016 /* Lesser General Public License for more details. */ 00017 /* */ 00018 /* You should have received a copy of the GNU Lesser General Public */ 00019 /* License along with this library; if not, write to the Free Software */ 00020 /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */ 00021 /* USA */ 00022 /*------------------------------------------------------------------------*/ 00027 #ifndef util_ThreadPool_hpp 00028 #define util_ThreadPool_hpp 00029 00030 #include <util/TPI.h> 00031 00032 namespace TPI { 00033 00034 typedef TPI_ThreadPool ThreadPool ; 00035 00036 //---------------------------------------------------------------------- 00039 int Run( void (*func)(void*,ThreadPool), void * arg , int = 0 ); 00040 00043 template<class Worker> 00044 int Run( Worker & worker , void (Worker::*method)(ThreadPool) , int = 0 ); 00045 00046 //---------------------------------------------------------------------- 00047 00048 inline 00049 int Set_lock_size( int n ) { return TPI_Set_lock_size( n ); } 00050 00051 inline 00052 int Lock( ThreadPool pool , int n ) { return TPI_Lock( pool , n ); } 00053 00054 inline 00055 int Trylock( ThreadPool pool , int n ) { return TPI_Trylock( pool , n ); } 00056 00057 inline 00058 int Unlock( ThreadPool pool , int n ) { return TPI_Unlock( pool , n ); } 00059 00066 class LockGuard { 00067 private: 00068 LockGuard(); 00069 LockGuard( const LockGuard & ); 00070 LockGuard & operator = ( const LockGuard & ); 00071 const ThreadPool m_pool ; 00072 const int m_value ; 00073 const int m_result ; 00074 public: 00075 operator int() const { return m_result ; } 00076 00077 explicit LockGuard( ThreadPool pool , unsigned i_lock ) 00078 : m_pool( pool ), m_value( i_lock ), m_result( TPI_Lock(pool,i_lock) ) {} 00079 00080 ~LockGuard() { TPI_Unlock( m_pool , m_value ); } 00081 }; 00082 00083 //---------------------------------------------------------------------- 00084 00085 inline 00086 int Rank( ThreadPool pool , int & rank , int & size ) 00087 { return TPI_Rank( pool , & rank , & size ); } 00088 00089 inline 00090 int Partition( int Rank , int Size , int N , int & I_local , int & N_local ) 00091 { return TPI_Partition( Rank , Size , N , & I_local , & N_local ); } 00092 00093 //---------------------------------------------------------------------- 00094 00095 inline 00096 int Init( int n ) { return TPI_Init( n ); } 00097 00098 inline 00099 int Finalize() { return TPI_Finalize(); } 00100 00101 inline 00102 int Size( int & number_allocated ) { return TPI_Size( & number_allocated ); } 00103 00104 inline 00105 int Concurrency() { return TPI_Concurrency(); } 00106 00107 inline 00108 double Walltime() { return TPI_Walltime(); } 00109 00110 //---------------------------------------------------------------------- 00111 //---------------------------------------------------------------------- 00112 00113 namespace { 00114 00115 template<class Worker> 00116 class WorkerMethodHelper { 00117 private: 00118 WorkerMethodHelper(); 00119 WorkerMethodHelper( const WorkerMethodHelper & ); 00120 WorkerMethodHelper & operator = ( const WorkerMethodHelper & ); 00121 00122 public: 00123 00124 typedef void (Worker::*Method)( ThreadPool ); 00125 00126 Worker & worker ; 00127 Method method ; 00128 00129 WorkerMethodHelper( Worker & w , Method m ) : worker(w), method(m) {} 00130 00131 static void run( void * arg , ThreadPool pool ) 00132 { 00133 try { 00134 WorkerMethodHelper & wm = * reinterpret_cast<WorkerMethodHelper*>(arg); 00135 (wm.worker.*wm.method)(pool); 00136 } catch(...){} 00137 } 00138 }; 00139 00140 } 00141 00142 //---------------------------------------------------------------------- 00143 //---------------------------------------------------------------------- 00144 00145 inline 00146 int Run( void (*func)( void * , ThreadPool ) , void * arg , int n ) 00147 { 00148 return TPI_Run( reinterpret_cast< TPI_parallel_subprogram >(func), arg , n ); 00149 } 00150 00151 template<class Worker> 00152 inline 00153 int Run( Worker & worker, void (Worker::*method)(ThreadPool) , int n ) 00154 { 00155 typedef WorkerMethodHelper<Worker> WM ; 00156 00157 WM tmp( worker , method ); 00158 00159 return TPI_Run( reinterpret_cast<TPI_parallel_subprogram>(& WM::run),&tmp,n); 00160 } 00161 00162 //---------------------------------------------------------------------- 00163 //---------------------------------------------------------------------- 00164 00165 } 00166 00167 #endif 00168
1.7.4