ITK  4.12.0
Insight Segmentation and Registration Toolkit
itkThreadPool.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkThreadPool_h
19 #define itkThreadPool_h
20 
21 #include "itkConfigure.h"
22 #include "itkIntTypes.h"
23 
24 #include "itkThreadSupport.h"
25 
26 #if defined(ITK_USE_PTHREADS)
27 #include <pthread.h>
28 #include <semaphore.h>
29 #include <unistd.h> // for sleep
30 #elif defined(ITK_USE_WIN32_THREADS)
31 #include <windows.h>
32 #endif
33 
34 #if defined __APPLE__
35 #include <mach/mach_init.h>
36 #include <mach/mach_error.h>
37 #include <mach/semaphore.h>
38 #include <mach/task.h>
39 #include <mach/task_info.h>
40 #endif
41 
42 #include <map>
43 #include <set>
44 
45 #include "itkThreadJob.h"
46 #include "itkObject.h"
47 #include "itkObjectFactory.h"
48 #include "itkSimpleFastMutexLock.h"
49 #include "itkMutexLockHolder.h"
50 
51 namespace itk
52 {
53 
72 class ITKCommon_EXPORT ThreadPool : public Object
73 {
74 public:
75 
77  typedef ThreadPool Self;
78  typedef Object Superclass;
81 
83  typedef int ThreadTimeType;
84  typedef unsigned int ThreadCountType;
86 
88  itkTypeMacro(ThreadPool, Object);
89 
91  static Pointer New();
92 
97  static Pointer GetInstance();
98 
100  ThreadProcessIdType AssignWork(ThreadJob worker);
101 
104  void InitializeThreads(ThreadCountType maxThreads);
105 
107  bool WaitForJobOnThreadHandle(ThreadProcessIdType handle);
108 
109 protected:
111  {
112  public:
114  int SemaphoreWait();
115  int SemaphorePost();
116 #if defined(__APPLE__)
117  semaphore_t m_Semaphore;
118 #elif defined(_WIN32) || defined(_WIN64)
119  HANDLE m_Semaphore;
120 #elif defined(ITK_USE_PTHREADS)
121  sem_t m_Semaphore;
122 #endif
123 
125 
126  private:
127  static int m_SemaphoreCount;
128  ThreadSemaphorePair() ITK_DELETED_FUNCTION;
129  };
130 
131  ThreadPool(); // Protected so that only the GetThreadPool can create a thread
132  // pool
133  virtual ~ThreadPool();
134 
135 private:
136  ITK_DISALLOW_COPY_AND_ASSIGN(ThreadPool);
137 
139  bool m_ScheduleForDestruction;
140 
142  ThreadCountType m_ThreadCount;
143 
145  static SimpleFastMutexLock m_NumberOfPendingJobsToBeRunMutex;
146 
148  unsigned int m_IdCounter;
149 
151  bool m_ExceptionOccurred;
152 
154 
155  typedef std::pair<ThreadJobIdType,ThreadJob> ThreadJobContainerPairType;
156 
157  typedef std::set<ThreadJobIdType> ThreadJobIdsContainerType;
158 
160 
166  ThreadJobContainerType m_WorkerQueue;
167 
169  static SimpleFastMutexLock m_WorkerQueueMutex;
170 
172  ThreadProcessIdContainerType m_ThreadHandles;
173 
176  enum {
177  JOB_THREADHANDLE_JUST_ADDED=-3, //means thread just added
178  JOB_THREADHANDLE_IS_FREE=-2, // means this particular threadhandle
179  // (thread) is free
180  JOB_THREADHANDLE_IS_DONE=-1 // means the thread finished with the
181  // assigned job and is waiting until
182  // WaitForJobOnThreadHandle method is called
183  // otherwise threadhandle is actively
184  // running a job.
185  };
186 
195  {
196 public:
197 #if defined(ITK_USE_WIN32_THREADS)
198  typedef DWORD WinThreadIdType;
199 #else
200  typedef unsigned long WinThreadIdType;
201 #endif
202  ThreadProcessIdentifiers(const int tnid,
203  const ThreadProcessIdType tph,
204  const WinThreadIdType winThreadId) :
205  m_ThreadNumericId(tnid),
206  m_ThreadProcessHandle(tph),
207  m_WinThreadId(winThreadId)
208  {
209  }
211 
215 private:
216  ThreadProcessIdentifiers() ITK_DELETED_FUNCTION;
217  };
218 
219  // the ThreadProcessIdentifiersVector ThreadSemHandlePairingQueue and
220  // ThreadSemHandlePairingForWaitQueue really want to be STL
221  // containers with more efficient searchability than O(N) But the
222  // pthread_t type isn't guaranteed to be an integral type so it
223  // can't be used as a Key on a keyed STL container.
225  ThreadProcessIdentifiersVecType m_ThreadProcessIdentifiersVector;
226 
227  //ThreadSemaphorePair *m_ThreadSemHandlePairingQueue;
229 
230  ThreadSemHandlePairingQueueType m_ThreadSemHandlePairingQueue;
231  ThreadSemHandlePairingQueueType m_ThreadSemHandlePairingForWaitQueue;
232 
234  static SimpleFastMutexLock m_ThreadProcessIdentifiersVectorMutex;
235 
241  const ThreadJob &FetchWork(ThreadProcessIdType t);
242 
248  void RemoveActiveId(ThreadJobIdType id);
249 
253  void AddThread();
254 
256  void WaitForThread(ThreadProcessIdType);
257 
261  ThreadProcessIdentifiers *FindThreadToRun();
262 
263  static Pointer m_ThreadPoolInstance;
265  static SimpleFastMutexLock m_ThreadPoolInstanceMutex;
266 
267  ThreadSemaphorePair* GetSemaphore(ThreadSemHandlePairingQueueType &q,ThreadProcessIdType threadHandle);
268 
269  ThreadSemaphorePair* GetSemaphoreForThread(ThreadProcessIdType threadHandle);
270 
271  ThreadSemaphorePair* GetSemaphoreForThreadWait(ThreadProcessIdType threadHandle);
272 
273  void DeallocateThreadSemSet(ThreadSemHandlePairingQueueType &q);
274 
276  static void * ThreadExecute(void *param);
277 
279  static bool CompareThreadHandles(ThreadProcessIdType t1, ThreadProcessIdType t2);
280 
282  ThreadProcessIdType GetThreadHandleForThreadId(ThreadIdType id);
283 
284 
285 };
286 
287 }
288 #endif
std::pair< ThreadJobIdType, ThreadJob > ThreadJobContainerPairType
Critical section locking class that can be allocated on the stack.
ThreadPool Self
Definition: itkThreadPool.h:77
std::vector< ThreadProcessIdentifiers > ThreadProcessIdentifiersVecType
This class is used to submit jobs to the thread pool. The thread job maintains important information ...
Definition: itkThreadJob.h:39
static Pointer New()
SmartPointer< Self > Pointer
Definition: itkThreadPool.h:79
ThreadJob::JobIdType ThreadJobIdType
Definition: itkThreadPool.h:85
std::map< ThreadJobIdType, ThreadJob > ThreadJobContainerType
std::set< ThreadJobIdType > ThreadJobIdsContainerType
std::vector< ThreadSemaphorePair * > ThreadSemHandlePairingQueueType
SmartPointer< const Self > ConstPointer
Definition: itkThreadPool.h:80
std::set< ThreadProcessIdType > ThreadProcessIdContainerType
ThreadProcessIdentifiers(const int tnid, const ThreadProcessIdType tph, const WinThreadIdType winThreadId)
unsigned int ThreadIdType
Definition: itkIntTypes.h:159
int ThreadProcessIdType
Thread pool manages the threads for itk.
Definition: itkThreadPool.h:72
unsigned int ThreadCountType
Definition: itkThreadPool.h:84
Base class for most ITK classes.
Definition: itkObject.h:59
ThreadProcessIdType m_ThreadProcessHandle