1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
/*=========================================================================
*
* Copyright NumFOCUS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
/*=========================================================================
*
* Portions of this file are subject to the VTK Toolkit Version 3 copyright.
*
* Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
*
* For complete copyright, license and disclaimer of warranty information
* please refer to the NOTICE file at the top of the ITK source tree.
*
*=========================================================================*/
#ifndef itkPlatformMultiThreader_h
#define itkPlatformMultiThreader_h
#include "itkMultiThreaderBase.h"
#include <mutex>
#include <memory>
namespace itk
{
/** \class PlatformMultiThreader
* \brief A class for performing multithreaded execution
*
* Multithreader is a class that provides support for multithreaded
* execution using Windows or POSIX threads.
* This class can be used to execute a single
* method on multiple threads, or to specify a method per thread.
*
* \ingroup OSSystemObjects
*
* \ingroup ITKCommon
*/
class ITKCommon_EXPORT PlatformMultiThreader : public MultiThreaderBase
{
public:
ITK_DISALLOW_COPY_AND_MOVE(PlatformMultiThreader);
/** Standard class type aliases. */
using Self = PlatformMultiThreader;
using Superclass = MultiThreaderBase;
using Pointer = SmartPointer<Self>;
using ConstPointer = SmartPointer<const Self>;
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** \see LightObject::GetNameOfClass() */
itkOverrideGetNameOfClassMacro(PlatformMultiThreader);
#if !defined(ITK_LEGACY_REMOVE)
/** Set/Get the maximum number of threads to use when multithreading. It
* will be clamped to the range [ 1, ITK_MAX_THREADS ] because several arrays
* are already statically allocated using the ITK_MAX_THREADS number.
* Therefore the caller of this method should check that the requested number
* of threads was accepted. Legacy: use MultiThreaderBase to invoke these. */
itkLegacyMacro(static void SetGlobalMaximumNumberOfThreads(ThreadIdType val))
{
itkGenericOutputMacro("Warning: SetGlobalMaximumNumberOfThreads should now be called on itk::MultiThreaderBase. It "
"can affect all MultiThreaderBase's derived classes in ITK");
Superclass::SetGlobalMaximumNumberOfThreads(val);
}
itkLegacyMacro(static ThreadIdType GetGlobalMaximumNumberOfThreads())
{
itkGenericOutputMacro("Warning: GetGlobalMaximumNumberOfThreads should now be called on itk::MultiThreaderBase. It "
"can affect all MultiThreaderBase's derived classes in ITK");
return Superclass::GetGlobalMaximumNumberOfThreads();
}
/** Set/Get the value which is used to initialize the NumberOfThreads in the
* constructor. It will be clamped to the range [1, m_GlobalMaximumNumberOfThreads ].
* Therefore the caller of this method should check that the requested number
* of threads was accepted. Legacy: use MultiThreaderBase to invoke these. */
itkLegacyMacro(static void SetGlobalDefaultNumberOfThreads(ThreadIdType val))
{
itkGenericOutputMacro("Warning: SetGlobalDefaultNumberOfThreads should now be called on itk::MultiThreaderBase. It "
"can affect all MultiThreaderBase's derived classes in ITK");
Superclass::SetGlobalDefaultNumberOfThreads(val);
}
itkLegacyMacro(static ThreadIdType GetGlobalDefaultNumberOfThreads())
{
itkGenericOutputMacro("Warning: GetGlobalDefaultNumberOfThreads should now be called on itk::MultiThreaderBase. It "
"can affect all MultiThreaderBase's derived classes in ITK");
return Superclass::GetGlobalDefaultNumberOfThreads();
}
#endif
/** Execute the SingleMethod (as define by SetSingleMethod) using
* m_NumberOfWorkUnits threads. As a side effect the m_NumberOfWorkUnits will be
* checked against the current m_GlobalMaximumNumberOfThreads and clamped if
* necessary. */
void
SingleMethodExecute() override;
/** Execute the MultipleMethods (as define by calling SetMultipleMethod for
* each of the required m_NumberOfWorkUnits methods) using m_NumberOfWorkUnits
* threads. As a side effect the m_NumberOfWorkUnits will be checked against the
* current m_GlobalMaximumNumberOfThreads and clamped if necessary. */
itkLegacyMacro(void MultipleMethodExecute());
/** Set the SingleMethod to f() and the UserData field of the
* WorkUnitInfo that is passed to it will be data.
* This method (and all the methods passed to SetMultipleMethod)
* must be of type itkThreadFunctionType and must take a single argument of
* type void *. */
void
SetSingleMethod(ThreadFunctionType, void * data) override;
/** Set the MultipleMethod at the given index to f() and the UserData
* field of the WorkUnitInfo that is passed to it will be data. */
itkLegacyMacro(void SetMultipleMethod(ThreadIdType index, ThreadFunctionType, void * data));
/** Create a new thread for the given function. Return a thread id
* which is a number between 0 and ITK_MAX_THREADS - 1. This
* id should be used to kill the thread at a later time.
* Deprecated. Use C++11 thread support instead. */
itkLegacyMacro(ThreadIdType SpawnThread(ThreadFunctionType, void * data));
/** Terminate the thread that was created with a SpawnThreadExecute()
* Deprecated. Use C++11 thread support instead. */
itkLegacyMacro(void TerminateThread(ThreadIdType thread_id));
void
SetMaximumNumberOfThreads(ThreadIdType numberOfThreads) override;
void
SetNumberOfWorkUnits(ThreadIdType numberOfWorkUnits) override;
struct WorkUnitInfo : MultiThreaderBase::WorkUnitInfo
{
int * ActiveFlag = nullptr;
std::shared_ptr<std::mutex> ActiveFlagLock;
};
protected:
PlatformMultiThreader();
~PlatformMultiThreader() override;
void
PrintSelf(std::ostream & os, Indent indent) const override;
private:
/** An array of thread info containing a thread id
* (0, 1, 2, .. ITK_MAX_THREADS-1), the thread count, and a pointer
* to void so that user data can be passed to each thread. */
WorkUnitInfo m_ThreadInfoArray[ITK_MAX_THREADS]{};
/** Storage of MutexFunctions and ints used to control spawned
* threads and the spawned thread ids. */
int m_SpawnedThreadActiveFlag[ITK_MAX_THREADS]{};
std::shared_ptr<std::mutex> m_SpawnedThreadActiveFlagMutex[ITK_MAX_THREADS]{};
ThreadProcessIdType m_SpawnedThreadProcessID[ITK_MAX_THREADS]{};
WorkUnitInfo m_SpawnedThreadInfoArray[ITK_MAX_THREADS]{};
#if !defined(ITK_LEGACY_REMOVE)
/** The methods to invoke. */
ThreadFunctionType m_MultipleMethod[ITK_MAX_THREADS]{};
/** Internal storage of the data. */
void * m_MultipleData[ITK_MAX_THREADS]{};
#endif
/** spawn a new thread for the SingleMethod */
ThreadProcessIdType
SpawnDispatchSingleMethodThread(WorkUnitInfo *);
/** wait for a thread in the threadpool to finish work */
void SpawnWaitForSingleMethodThread(ThreadProcessIdType);
/** Friends of Multithreader.
* ProcessObject is a friend so that it can call PrintSelf() on its
* Multithreader. */
friend class ProcessObject;
};
} // end namespace itk
#endif // itkPlatformMultiThreader_h
|