00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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