00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef __mitkSPMD_h
00011 #define __mitkSPMD_h
00012
00013 #include "mitkObject.h"
00014
00015 class mitkMutex;
00016 class mitkConditionVariable;
00017 class mitkSPMD;
00018
00026 class MITK_COMMON_API mitkBarrier:public mitkObject
00027 {
00028 public:
00033 void Synchronize();
00034 friend class mitkSPMD;
00035 private:
00036 mitkBarrier(int NumberOfThreads);
00037 virtual ~mitkBarrier();
00038 mitkBarrier(const mitkBarrier&);
00039 void operator = (const mitkBarrier&);
00040
00041 int m_NumberOfThreads;
00042 int m_Count;
00043 mitkConditionVariable *m_CV;
00044 };
00045
00055 class MITK_COMMON_API mitkSPMD:public mitkObject
00056 {
00057 public:
00058 MITK_TYPE(mitkSPMD,mitkObject)
00065 void SetNumberOfThreads(int NumberOfThreads);
00071 int GetNumberOfThreads() const
00072 {
00073 return m_NumberOfThreads;
00074 }
00078 void RunSPMD();
00084 static int GetGlobalDefaultNumberOfThreads();
00085
00086 protected:
00087 mitkSPMD();
00088 virtual ~mitkSPMD();
00089
00090 virtual void SPMDInit(){};
00091
00092 virtual void ThreadExecute(int ThreadID)=0;
00093
00094 virtual void SPMDFinish(){};
00095
00096 void Synchronize()
00097 {
00098 if (m_Barrier) m_Barrier->Synchronize();
00099 }
00100
00101 mitkBarrier *GetBarrier(){return m_Barrier;}
00102
00103 private:
00104 mitkSPMD(const mitkSPMD&);
00105 void operator = (const mitkSPMD&);
00106 int m_NumberOfThreads;
00107 mitkBarrier *m_Barrier;
00108
00109 };
00110
00116 class MITK_COMMON_API mitkSPMDDelegate: public mitkSPMD
00117 {
00118 public:
00119 MITK_TYPE(mitkSPMDDelegate,mitkSPMD)
00120 void SetParameter(void *param)
00121 {
00122 m_Param=param;
00123 }
00124 protected:
00125 mitkSPMDDelegate() {m_Param=NULL;}
00126 virtual ~mitkSPMDDelegate(){}
00127 void *GetParameter()
00128 {
00129 return m_Param;
00130 }
00131 private:
00132 mitkSPMDDelegate(const mitkSPMDDelegate&);
00133 void operator = (const mitkSPMDDelegate&);
00134 void *m_Param;
00135 };
00136
00144 class mitkSPMDStatic: public mitkSPMDDelegate
00145 {
00146 public:
00147 mitkSPMDStatic(void (*ThreadedFunction)(int,int,void *,mitkBarrier*),
00148 void (*InitFunction)(int,void *)=NULL,
00149 void (*FinishFunction)(int,void *)=NULL)
00150 {
00151 m_ThreadedFunction=ThreadedFunction;
00152 m_InitFunction=InitFunction;
00153 m_FinishFunction=FinishFunction;
00154 }
00155
00156 protected:
00157 virtual ~mitkSPMDStatic(){}
00158 virtual void SPMDInit()
00159 {
00160 if (m_InitFunction) m_InitFunction(GetNumberOfThreads(),GetParameter());
00161 }
00162 virtual void ThreadExecute(int ThreadID)
00163 {
00164 m_ThreadedFunction(ThreadID,GetNumberOfThreads(),GetParameter(),GetBarrier());
00165 }
00166 virtual void SPMDFinish()
00167 {
00168 if (m_FinishFunction) m_FinishFunction(GetNumberOfThreads(),GetParameter());
00169 }
00170 private:
00171 mitkSPMDStatic(const mitkSPMDStatic&);
00172 void operator = (const mitkSPMDStatic&);
00173 void (*m_InitFunction)(int,void *);
00174 void (*m_FinishFunction)(int,void *);
00175 void (*m_ThreadedFunction)(int,int,void *,mitkBarrier*);
00176 };
00177
00185 template<class T>
00186 class mitkSPMDMember: public mitkSPMDDelegate
00187 {
00188 public:
00189 mitkSPMDMember(T* object,void (T::*ThreadedMember)(int,int,void*,mitkBarrier*),
00190 void (T::*InitMember)(int,void*)=NULL,
00191 void (T::*FinishMember)(int,void*)=NULL)
00192 {
00193 m_object=object;
00194 m_ThreadedMember=ThreadedMember;
00195 m_InitMember=InitMember;
00196 m_FinishMember=FinishMember;
00197 }
00198 protected:
00199 virtual ~mitkSPMDMember(){}
00200 virtual void SPMDInit()
00201 {
00202 if (m_InitMember) (m_object->*m_InitMember)(GetNumberOfThreads(),GetParameter());
00203 }
00204 virtual void ThreadExecute(int ThreadID)
00205 {
00206 (m_object->*m_ThreadedMember)(ThreadID,GetNumberOfThreads(),GetParameter(),GetBarrier());
00207 }
00208 virtual void SPMDFinish()
00209 {
00210 if (m_FinishMember) (m_object->*m_FinishMember)(GetNumberOfThreads(),GetParameter());
00211 }
00212
00213 private:
00214 mitkSPMDMember(const mitkSPMDMember&);
00215 void operator = (const mitkSPMDMember&);
00216 T *m_object;
00217 void (T::*m_InitMember)(int,void*);
00218 void (T::*m_FinishMember)(int,void*);
00219 void (T::*m_ThreadedMember)(int,int,void*,mitkBarrier*);
00220 };
00221
00222 #define MITK_SPMD_MEMBER1(Class,ObjectPointer,ThreadedMember)\
00223 mitkSPMDMember<Class>(ObjectPointer,&Class::ThreadedMember)
00224
00225 #define MITK_SPMD_MEMBER2(Class,ObjectPointer,ThreadedMember,InitMember)\
00226 mitkSPMDMember<Class>(ObjectPointer,&Class::ThreadedMember,&Class::InitMember)
00227
00228 #define MITK_SPMD_MEMBER3(Class,ObjectPointer,ThreadedMember,InitMember,FinishMember)\
00229 mitkSPMDMember<Class>(ObjectPointer,&Class::ThreadedMember,&Class::InitMember,&Class::FinishMember)
00230
00231
00232 #endif
00233