KWStyle - itkMultiThreader.h
 
Matrix View
Description

1 /*=========================================================================
2
3   Program:   Insight Segmentation & Registration Toolkit
4   Module:    $RCSfile: itkMultiThreader.h.html,v $
5   Language:  C++
6   Date:      $Date: 2006/01/17 19:15:42 $
7   Version:   $Revision: 1.4 $
8
9   Copyright (c) Insight Software Consortium. All rights reserved.
10   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11
12   Portions of this code are covered under the VTK copyright.
13   See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.
14
15      This software is distributed WITHOUT ANY WARRANTY; without even 
16      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
17 IND *****PURPOSE.  See the above copyright notices for more information.
18
19 =========================================================================*/
20 #ifndef __itkMultiThreader_h
21 #define __itkMultiThreader_h
22
23 #include "itkObject.h"
24 #include "itkMutexLock.h"
25
26 #ifdef ITK_USE_SPROC
27 #include <sys/types.h>
28 #include <sys/resource.h>
29 #include <sys/types.h>
30 #include <sys/prctl.h>
31 #include <wait.h>
32 #include <errno.h>
33 #include <ulocks.h>
34 #include <fcntl.h>
35 #include <unistd.h>
36 #include <stdlib.h>
37 #include <signal.h>
38 #include <sys/signal.h>
39 #include <sys/sysmp.h>
40 #include <sys/errno.h>
41 #include <sys/syssgi.h>
42
43 extern "C" {
44 #include <sys/pmo.h>
45 #include <fetchop.h>
46 IND }
47 #endif
48
49 #ifdef ITK_USE_PTHREADS
50 #include <pthread.h>
51 #endif
52
53 namespace itk
54 {
55 /** \class MultiThreader
56  * \brief A class for performing multithreaded execution
57  *
58  * Multithreader is a class that provides support for multithreaded
59  * execution using sproc() on an SGI, or pthread_create on any platform
60  * supporting POSIX threads.  This class can be used to execute a single
61  * method on multiple threads, or to specify a method per thread.
62  *
63  * \ingroup OSSystemObejcts
64  *
65  * \par Note
66  * If ITK_USE_SPROC is defined, then sproc() will be used to create
67  * multiple threads on an SGI. If ITK_USE_PTHREADS is defined, then
68  * pthread_create() will be used to create multiple threads (on
69  * a sun, for example). */
70
71 // The maximum number of threads allowed
72 #ifdef ITK_USE_SPROC
73 #define ITK_MAX_THREADS              128
74 #endif
75
76 #ifdef ITK_USE_PTHREADS
77 #define ITK_MAX_THREADS              128
78 #endif
79
80 #ifdef ITK_USE_WIN32_THREADS
81 #define ITK_MAX_THREADS              128
82 #endif
83
84 // cygwin threads are unreliable
85 #ifdef __CYGWIN__
86 #undef ITK_MAX_THREADS
87 #define ITK_MAX_THREADS 128 
88 #endif
89
90 // mingw threads cause crashes  so limit to 1
91 #if defined(__MINGW32__)
92 #undef ITK_MAX_THREADS
93 #define ITK_MAX_THREADS 1 
94 #endif
95   
96 // On some sgi machines, threads and stl don't mix so limit to 1
97 #if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730
98 #undef ITK_MAX_THREADS
99 #define ITK_MAX_THREADS 1 
100 #endif
101   
102 #ifndef ITK_MAX_THREADS
103 #define ITK_MAX_THREADS 1
104 #endif
105
106 /** \par Note
107  * If ITK_USE_PTHREADS is defined, then the multithreaded
108  * function is of type void *, and returns NULL
109  * Otherwise the type is void which is correct for WIN32
110  * and SPROC. */
111 #ifdef ITK_USE_SPROC
112 typedef int ThreadProcessIDType;
113 #endif
114
115 #ifdef ITK_USE_PTHREADS
116 TDR typedef void *(*ThreadFunctionType)(void *);
117 TDA typedef pthread_t ThreadProcessIDType;
118 #define ITK_THREAD_RETURN_VALUE  NULL
119 #define ITK_THREAD_RETURN_TYPE   void *
120 #endif
121
122 #ifdef ITK_USE_WIN32_THREADS
123 typedef LPTHREAD_START_ROUTINE ThreadFunctionType;
124 TDA typedef HANDLE ThreadProcessIDType;
125 #define ITK_THREAD_RETURN_VALUE 0
126 #define ITK_THREAD_RETURN_TYPE DWORD __stdcall
127 #endif
128
129 #ifndef ITK_THREAD_RETURN_VALUE
130 TDR typedef void (*ThreadFunctionType)(void *);
131 TDA typedef int ThreadProcessIDType;
132 #define ITK_THREAD_RETURN_VALUE
133 #define ITK_THREAD_RETURN_TYPE void
134 #endif
135   
136 class ITKCommon_EXPORT MultiThreader : public Object 
137 {
138 public:
139   /** Standard class typedefs. */
140   typedef MultiThreader         Self;
141 TDA   typedef Object  Superclass;
142 TDA   typedef SmartPointer<Self>  Pointer;
143 TDA   typedef SmartPointer<const Self>  ConstPointer;
144   
145   /** Method for creation through the object factory. */
146   itkNewMacro(Self);  
147
148   /** Run-time type information (and related methods). */
149   itkTypeMacro(MultiThreader, Object);
150
151   /** Get/Set the number of threads to create. It will be clamped to the range
152    * 1 - ITK_MAX_THREADS, so the caller of this method should check that the
153    * requested number of threads was accepted. */
154   itkSetClampMacro( NumberOfThreads, int, 1, ITK_MAX_THREADS );
155   itkGetMacro( NumberOfThreads, int );
156     
157   /** Set/Get the maximum number of threads to use when multithreading.
158    * This limits and overrides any other settings for multithreading.
159    * A value of zero indicates no limit. */
160   static void SetGlobalMaximumNumberOfThreads(int val);
161   static int  GetGlobalMaximumNumberOfThreads();
162   
163   /** Set/Get the value which is used to initialize the NumberOfThreads
164    * in the constructor.  Initially this default is set to the number of 
165    * processors or 8 (which ever is less). */
166   static void SetGlobalDefaultNumberOfThreads(int val);
167   static int  GetGlobalDefaultNumberOfThreads();
168   
169   /** Execute the SingleMethod (as define by SetSingleMethod) using
170    * m_NumberOfThreads threads. */
171   void SingleMethodExecute();
172
173   /** Execute the MultipleMethods (as define by calling SetMultipleMethod
174    * for each of the required m_NumberOfThreads methods) using
175    * m_NumberOfThreads threads. */
176   void MultipleMethodExecute();
177   
178   /** Set the SingleMethod to f() and the UserData field of the
179    * ThreadInfoStruct that is passed to it will be data.
180    * This method (and all the methods passed to SetMultipleMethod)
181    * must be of type itkThreadFunctionType and must take a single argument of
182    * type void *. */
183   void SetSingleMethod(ThreadFunctionType, void *data );
184   
185   /** Set the MultipleMethod at the given index to f() and the UserData 
186    * field of the ThreadInfoStruct that is passed to it will be data. */
187   void SetMultipleMethod( int index, ThreadFunctionType, void *data ); 
188
189   /** Create a new thread for the given function. Return a thread id
190    * which is a number between 0 and ITK_MAX_THREADS - 1. This id should
191    * be used to kill the thread at a later time. */
192   int SpawnThread( ThreadFunctionType, void *data );
193
194   /** Terminate the thread that was created with a SpawnThreadExecute() */
195   void TerminateThread( int thread_id );
196   
197 #ifdef ITK_USE_SPROC
198   static bool GetInitialized()
199 IND **{ return m_Initialized; }
200   static usptr_t * GetThreadArena()
201 IND **{ return m_ThreadArena; }
202
203   static void Initialize();
204 #endif
205   
206   /** This is the structure that is passed to the thread that is
207    * created from the SingleMethodExecute, MultipleMethodExecute or
208    * the SpawnThread method. It is passed in as a void *, and it is up
209    * to the method to cast correctly and extract the information.  The
210    * ThreadID is a number between 0 and NumberOfThreads-1 that
211    * indicates the id of this thread. The NumberOfThreads is
212    * this->NumberOfThreads for threads created from
213    * SingleMethodExecute or MultipleMethodExecute, and it is 1 for
214    * threads created from SpawnThread.  The UserData is the (void
215    * *)arg passed into the SetSingleMethod, SetMultipleMethod, or
216    * SpawnThread method. */
217 #ifdef ThreadInfoStruct
218 IND #undef ThreadInfoStruct
219 #endif
220   struct ThreadInfoStruct
221 IND **{
222 #ifdef ITK_USE_SPROC
223     char Pad1[128];
224 #endif
225     int                 ThreadID;
226     int                 NumberOfThreads;
227     int                 *ActiveFlag;
228     MutexLock::Pointer  ActiveFlagLock;
229     void                *UserData;
230     ThreadFunctionType  ThreadFunction;
231 LEN     enum {SUCCESS, ITK_EXCEPTION, ITK_PROCESS_ABORTED_EXCEPTION, STD_EXCEPTION, UNKNOWN} ThreadExitCode;
232 #ifdef ITK_USE_SPROC
233     char Pad2[128];
234 #endif
235 IND **};
236   
237 protected:
238   MultiThreader();
239   ~MultiThreader();
240   void PrintSelf(std::ostream& os, Indent indent) const;
241
242 private:
243   
244 #ifdef ITK_USE_SPROC
245   static bool m_Initialized;
246   static usptr_t * m_ThreadArena;
247   static int m_DevzeroFd;
248 #endif
249
250   MultiThreader(const Self&); //purposely not implemented
251   void operator=(const Self&); //purposely not implemented
252
253   /** The number of threads to use. */
254   int                        m_NumberOfThreads;
255
256   /** An array of thread info containing a thread id
257    *  (0, 1, 2, .. ITK_MAX_THREADS-1), the thread count, and a pointer
258    *  to void so that user data can be passed to each thread. */
259   ThreadInfoStruct           m_ThreadInfoArray[ITK_MAX_THREADS];
260
261   /** The methods to invoke. */
262   ThreadFunctionType         m_SingleMethod;
263   ThreadFunctionType         m_MultipleMethod[ITK_MAX_THREADS];
264   
265   /** Storage of MutexFunctions and ints used to control spawned 
266    *  threads and the spawned thread ids. */
267   int                        m_SpawnedThreadActiveFlag    [ITK_MAX_THREADS];
268   MutexLock::Pointer         m_SpawnedThreadActiveFlagLock[ITK_MAX_THREADS];
269   ThreadProcessIDType        m_SpawnedThreadProcessID     [ITK_MAX_THREADS];
270   ThreadInfoStruct           m_SpawnedThreadInfoArray     [ITK_MAX_THREADS];
271   
272   /** Internal storage of the data. */
273   void                       *m_SingleData;
274   void                       *m_MultipleData[ITK_MAX_THREADS];
275
276   /** Statics variables. */
277   static int                  m_GlobalMaximumNumberOfThreads;
278   static int                  m_GlobalDefaultNumberOfThreads;
279   
280   /** Static function used as a "proxy callback" by the MultiThreader.  The
281    * threading library will call this routine for each thread, which
282    * will delegate the control to the prescribed SingleMethod. This
283    * routine acts as an intermediary between the MultiThreader and the
284    * user supplied callback (SingleMethod) in order to catch any
285    * exceptions thrown by the threads. */
286   static ITK_THREAD_RETURN_TYPE SingleMethodProxy( void *arg );
287
288   /** Spawn a thread for the prescribed SingleMethod.  This routine
289    * spawns a thread to the SingleMethodProxy which runs the
290    * prescribed SingleMethod.  The SingleMethodProxy allows for
291    * exceptions within a thread to be naively handled. A similar
292    * abstraction needs to be added for MultipleMethod and
293    * SpawnThread. */
294   ThreadProcessIDType DispatchSingleMethodThread(ThreadInfoStruct *);
295
296   /** Wait for a thread running the prescribed SingleMethod. A similar
297    * abstraction needs to be added for MultipleMethod (SpawnThread
298    * already has a routine to do this. */
299   void WaitForSingleMethodThread(ThreadProcessIDType);
300
301   
302   /** Friends of Multithreader.
303    * ProcessObject is a friend so that it can call PrintSelf() on its
304    * Multithreader. */
305   friend class ProcessObject;
306 }; 
307  
308 }  // end namespace itk
309 #endif
310

Generated by KWStyle 1.0b on Tuesday January,17 at 02:14:26PM
© Kitware Inc.