00001 /*========================================================================= 00002 00003 Program: Open IGT Link Library 00004 Module: $HeadURL: http://svn.na-mic.org/NAMICSandBox/trunk/OpenIGTLink/Source/igtlMultiThreader.h $ 00005 Language: C++ 00006 Date: $Date: 2009-11-12 19:53:57 -0500 (Thu, 12 Nov 2009) $ 00007 Version: $Revision: 5331 $ 00008 00009 Copyright (c) Insight Software Consortium. All rights reserved. 00010 00011 This software is distributed WITHOUT ANY WARRANTY; without even 00012 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00013 PURPOSE. See the above copyright notices for more information. 00014 00015 =========================================================================*/ 00016 /*========================================================================= 00017 00018 Program: Visualization Toolkit 00019 Module: $RCSfile: vtkMultiThreader.h,v $ 00020 00021 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 00022 All rights reserved. 00023 See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 00024 00025 This software is distributed WITHOUT ANY WARRANTY; without even 00026 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00027 PURPOSE. See the above copyright notice for more information. 00028 00029 =========================================================================*/ 00030 // .NAME igtlMultiThreader - A class for performing multithreaded execution 00031 // .SECTION Description 00032 // igtlMultithreader is a class that provides support for multithreaded 00033 // execution using sproc() on an SGI, or pthread_create on any platform 00034 // supporting POSIX threads. This class can be used to execute a single 00035 // method on multiple threads, or to specify a method per thread. 00036 00037 #ifndef __igtlMultiThreader_h 00038 #define __igtlMultiThreader_h 00039 00040 #include "igtlObject.h" 00041 #include "igtlObjectFactory.h" 00042 #include "igtlMacro.h" 00043 #include "igtlMutexLock.h" 00044 00045 00046 #ifdef OpenIGTLink_USE_SPROC 00047 #include <sys/types.h> // Needed for unix implementation of sproc 00048 #include <unistd.h> // Needed for unix implementation of sproc 00049 #endif 00050 00051 #if defined(OpenIGTLink_USE_PTHREAD) || defined(OpenIGTLink_HP_PTHREAD) 00052 #include <pthread.h> // Needed for PTHREAD implementation of mutex 00053 #include <sys/types.h> // Needed for unix implementation of pthreads 00054 #include <unistd.h> // Needed for unix implementation of pthreads 00055 #endif 00056 00057 namespace igtl 00058 { 00059 00060 // If OpenIGTLink_USE_SPROC is defined, then sproc() will be used to create 00061 // multiple threads on an SGI. If OpenIGTLink_USE_PTHREAD is defined, then 00062 // pthread_create() will be used to create multiple threads (on 00063 // a sun, for example) 00064 00065 // Defined in igtlSystemIncludes.h: 00066 // IGTL_MAX_THREADS 00067 00068 // If OpenIGTLink_USE_PTHREADS is defined, then the multithreaded 00069 // function is of type void *, and returns NULL 00070 // Otherwise the type is void which is correct for WIN32 00071 // and SPROC 00072 //BTX 00073 00074 // The maximum number of threads allowed 00075 #ifdef OpenIGTLink_USE_SPROC 00076 #define IGTL_MAX_THREADS 128 00077 #endif 00078 00079 #ifdef OpenIGTLink_USE_PTHREADS 00080 #define IGTL_MAX_THREADS 128 00081 #endif 00082 00083 #ifdef OpenIGTLink_USE_WIN32_THREADS 00084 #define IGTL_MAX_THREADS 128 00085 #endif 00086 00087 // cygwin threads are unreliable 00088 #ifdef __CYGWIN__ 00089 #undef IGTL_MAX_THREADS 00090 #define IGTL_MAX_THREADS 128 00091 #endif 00092 00093 // mingw threads cause crashes so limit to 1 00094 #if defined(__MINGW32__) 00095 #undef IGTL_MAX_THREADS 00096 #define IGTL_MAX_THREADS 1 00097 #endif 00098 00099 // On some sgi machines, threads and stl don't mix so limit to 1 00100 #if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 00101 #undef IGTL_MAX_THREADS 00102 #define IGTL_MAX_THREADS 1 00103 #endif 00104 00105 #ifndef IGTL_MAX_THREADS 00106 #define IGTL_MAX_THREADS 1 00107 #endif 00108 00109 #ifdef OpenIGTLink_USE_SPROC 00110 typedef int ThreadProcessIDType; 00111 typedef int MultiThreaderIDType; 00112 #endif 00113 00114 #ifdef OpenIGTLink_USE_PTHREADS 00115 typedef void *(*ThreadFunctionType)(void *); 00116 typedef pthread_t ThreadProcessIDType; 00117 typedef pthread_t MultiThreaderIDType; 00118 #endif 00119 00120 #ifdef OpenIGTLink_USE_WIN32_THREADS 00121 typedef igtlWindowsLPTHREAD_START_ROUTINE ThreadFunctionType; 00122 typedef igtlWindowsHANDLE ThreadProcessIDType; 00123 typedef igtlWindowsDWORD MultiThreaderIDType; 00124 #endif 00125 00126 #if !defined(OpenIGTLink_USE_PTHREADS) && !defined(OpenIGTLink_USE_WIN32_THREADS) 00127 typedef void (*ThreadFunctionType)(void *); 00128 typedef int ThreadProcessIDType; 00129 typedef int MultiThreaderIDType; 00130 #endif 00131 //ETX 00132 00133 00134 class IGTLCommon_EXPORT MultiThreader : public Object 00135 { 00136 public: 00138 typedef MultiThreader Self; 00139 typedef Object Superclass; 00140 typedef SmartPointer<Self> Pointer; 00141 typedef SmartPointer<const Self> ConstPointer; 00142 00143 igtlNewMacro(Self); 00144 igtlTypeMacro(MultiThreader, Object); 00145 00146 void PrintSelf(std::ostream& os); 00147 00148 // Description: 00149 // This is the structure that is passed to the thread that is 00150 // created from the SingleMethodExecute, MultipleMethodExecute or 00151 // the SpawnThread method. It is passed in as a void *, and it is 00152 // up to the method to cast correctly and extract the information. 00153 // The ThreadID is a number between 0 and NumberOfThreads-1 that indicates 00154 // the id of this thread. The NumberOfThreads is this->NumberOfThreads for 00155 // threads created from SingleMethodExecute or MultipleMethodExecute, 00156 // and it is 1 for threads created from SpawnThread. 00157 // The UserData is the (void *)arg passed into the SetSingleMethod, 00158 // SetMultipleMethod, or SpawnThread method. 00159 00160 //BTX 00161 #define ThreadInfoStruct MultiThreader::ThreadInfo 00162 class ThreadInfo 00163 { 00164 public: 00165 int ThreadID; 00166 int NumberOfThreads; 00167 int *ActiveFlag; 00168 MutexLock::Pointer ActiveFlagLock; 00169 void *UserData; 00170 }; 00171 //ETX 00172 00173 // Description: 00174 // Get/Set the number of threads to create. It will be clamped to the range 00175 // 1 - IGTL_MAX_THREADS, so the caller of this method should check that the 00176 // requested number of threads was accepted. 00177 igtlSetClampMacro( NumberOfThreads, int, 1, IGTL_MAX_THREADS ); 00178 virtual int GetNumberOfThreads(); 00179 00180 // Description: 00181 // Set/Get the maximum number of threads to use when multithreading. 00182 // This limits and overrides any other settings for multithreading. 00183 // A value of zero indicates no limit. 00184 static void SetGlobalMaximumNumberOfThreads(int val); 00185 static int GetGlobalMaximumNumberOfThreads(); 00186 00187 // Description: 00188 // Set/Get the value which is used to initialize the NumberOfThreads 00189 // in the constructor. Initially this default is set to the number of 00190 // processors or IGTL_MAX_THREADS (which ever is less). 00191 static void SetGlobalDefaultNumberOfThreads(int val); 00192 static int GetGlobalDefaultNumberOfThreads(); 00193 00194 // These methods are excluded from Tcl wrapping 1) because the 00195 // wrapper gives up on them and 2) because they really shouldn't be 00196 // called from a script anyway. 00197 //BTX 00198 00199 // Description: 00200 // Execute the SingleMethod (as define by SetSingleMethod) using 00201 // this->NumberOfThreads threads. 00202 void SingleMethodExecute(); 00203 00204 // Description: 00205 // Execute the MultipleMethods (as define by calling SetMultipleMethod 00206 // for each of the required this->NumberOfThreads methods) using 00207 // this->NumberOfThreads threads. 00208 void MultipleMethodExecute(); 00209 00210 // Description: 00211 // Set the SingleMethod to f() and the UserData field of the 00212 // ThreadInfo that is passed to it will be data. 00213 // This method (and all the methods passed to SetMultipleMethod) 00214 // must be of type ThreadFunctionType and must take a single argument of 00215 // type void *. 00216 void SetSingleMethod(ThreadFunctionType, void *data ); 00217 00218 // Description: 00219 // Set the MultipleMethod at the given index to f() and the UserData 00220 // field of the ThreadInfo that is passed to it will be data. 00221 void SetMultipleMethod( int index, ThreadFunctionType, void *data ); 00222 00223 // Description: 00224 // Create a new thread for the given function. Return a thread id 00225 // which is a number between 0 and IGTL_MAX_THREADS - 1. This id should 00226 // be used to kill the thread at a later time. 00227 int SpawnThread( ThreadFunctionType, void *data ); 00228 00229 // Description: 00230 // Terminate the thread that was created with a SpawnThreadExecute() 00231 void TerminateThread( int thread_id ); 00232 00233 // Description: 00234 // Get the thread identifier of the calling thread. 00235 static MultiThreaderIDType GetCurrentThreadID(); 00236 00237 // Description: 00238 // Check whether two thread identifiers refer to the same thread. 00239 static int ThreadsEqual(MultiThreaderIDType t1, 00240 MultiThreaderIDType t2); 00241 00242 protected: 00243 MultiThreader(); 00244 ~MultiThreader(); 00245 00246 // The number of threads to use 00247 int m_NumberOfThreads; 00248 00249 // An array of thread info containing a thread id 00250 // (0, 1, 2, .. IGTL_MAX_THREADS-1), the thread count, and a pointer 00251 // to void so that user data can be passed to each thread 00252 ThreadInfo m_ThreadInfoArray[IGTL_MAX_THREADS]; 00253 00254 // The methods 00255 ThreadFunctionType m_SingleMethod; 00256 ThreadFunctionType m_MultipleMethod[IGTL_MAX_THREADS]; 00257 00258 // Storage of MutexFunctions and ints used to control spawned 00259 // threads and the spawned thread ids 00260 int m_SpawnedThreadActiveFlag[IGTL_MAX_THREADS]; 00261 MutexLock::Pointer m_SpawnedThreadActiveFlagLock[IGTL_MAX_THREADS]; 00262 ThreadProcessIDType m_SpawnedThreadProcessID[IGTL_MAX_THREADS]; 00263 ThreadInfo m_SpawnedThreadInfoArray[IGTL_MAX_THREADS]; 00264 00265 //ETX 00266 00267 // Internal storage of the data 00268 void *m_SingleData; 00269 void *m_MultipleData[IGTL_MAX_THREADS]; 00270 00271 private: 00272 MultiThreader(const MultiThreader&); // Not implemented. 00273 void operator=(const MultiThreader&); // Not implemented. 00274 }; 00275 00276 } // namespace igtl 00277 #endif 00278 00279 00280 00281 00282 00283