00001 /* 00002 // 00003 // Copyright 1997-2009 Torsten Rohlfing 00004 // Copyright 2004-2010 SRI International 00005 // 00006 // This file is part of the Computational Morphometry Toolkit. 00007 // 00008 // http://www.nitrc.org/projects/cmtk/ 00009 // 00010 // The Computational Morphometry Toolkit is free software: you can 00011 // redistribute it and/or modify it under the terms of the GNU General Public 00012 // License as published by the Free Software Foundation, either version 3 of 00013 // the License, or (at your option) any later version. 00014 // 00015 // The Computational Morphometry Toolkit is distributed in the hope that it 00016 // will be useful, but WITHOUT ANY WARRANTY; without even the implied 00017 // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU General Public License along 00021 // with the Computational Morphometry Toolkit. If not, see 00022 // <http://www.gnu.org/licenses/>. 00023 // 00024 // $Revision: 2398 $ 00025 // 00026 // $LastChangedDate: 2010-10-05 14:54:37 -0700 (Tue, 05 Oct 2010) $ 00027 // 00028 // $LastChangedBy: torstenrohlfing $ 00029 // 00030 */ 00031 00032 #ifndef __cmtkThreadPool_h_included_ 00033 #define __cmtkThreadPool_h_included_ 00034 00035 #include <cmtkconfig.h> 00036 00037 #include <System/cmtkCannotBeCopied.h> 00038 00039 #include <System/cmtkThreadSystemTypes.h> 00040 #include <System/cmtkThreadSemaphore.h> 00041 #include <System/cmtkMutexLock.h> 00042 #include <System/cmtkSmartPtr.h> 00043 00044 #include <vector> 00045 00046 namespace 00047 cmtk 00048 { 00049 00105 class ThreadPool : 00107 private CannotBeCopied 00108 { 00109 public: 00111 typedef ThreadPool Self; 00112 00114 typedef SmartPointer<Self> SmartPtr; 00115 00124 typedef void (*TaskFunction)( void *const args, 00125 const size_t taskIdx, 00126 const size_t taskCnt, 00127 const size_t threadIdx, 00128 const size_t threadCont 00129 ); 00130 00136 ThreadPool( const size_t nThreads = 0 ); 00137 00139 ~ThreadPool(); 00140 00142 size_t GetNumberOfThreads() const 00143 { 00144 return this->m_NumberOfThreads; 00145 } 00146 00148 template<class TParam> 00149 void Run( TaskFunction taskFunction, 00150 std::vector<TParam>& taskParameters, 00151 const size_t numberOfTasksOverride = 0 00152 ); 00153 00155 void ThreadFunction( const size_t threadIdx ); 00156 00162 static Self& GetGlobalThreadPool(); 00163 00165 class ThreadPoolArg 00166 { 00167 public: 00169 ThreadPool* m_Pool; 00170 00172 size_t m_Index; 00173 }; 00174 00175 private: 00177 ThreadSemaphore m_TaskWaitingSemaphore; 00178 00180 ThreadSemaphore m_ThreadWaitingSemaphore; 00181 00183 size_t m_NumberOfTasks; 00184 00186 size_t m_NextTaskIndex; 00187 00189 MutexLock m_NextTaskIndexLock; 00190 00192 TaskFunction m_TaskFunction; 00193 00195 std::vector<void*> m_TaskParameters; 00196 00198 std::vector<Self::ThreadPoolArg> m_ThreadArgs; 00199 00201 size_t m_NumberOfThreads; 00202 00203 #ifdef CMTK_BUILD_SMP 00204 00205 std::vector<ThreadIDType> m_ThreadID; 00206 00207 #ifdef _MSC_VER 00208 00209 std::vector<HANDLE> m_ThreadHandles; 00210 #endif 00211 #endif 00212 00214 bool m_ThreadsRunning; 00215 00220 bool m_ContinueThreads; 00221 00223 void StartThreads(); 00224 00226 void EndThreads(); 00227 }; 00228 00229 } // namespace cmtk 00230 00232 extern "C" CMTK_THREAD_RETURN_TYPE cmtkThreadPoolThreadFunction( CMTK_THREAD_ARG_TYPE arg ); 00233 00234 #include "cmtkThreadPool.txx" 00235 00236 #endif // #ifndef __cmtkThreadPool_h_included_