File: itkPlatformMultiThreader.h

package info (click to toggle)
insighttoolkit5 5.4.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 704,588 kB
  • sloc: cpp: 784,579; ansic: 628,724; xml: 44,704; fortran: 34,250; python: 22,934; sh: 4,078; pascal: 2,636; lisp: 2,158; makefile: 461; yacc: 328; asm: 205; perl: 203; lex: 146; tcl: 132; javascript: 98; csh: 81
file content (189 lines) | stat: -rw-r--r-- 7,982 bytes parent folder | download | duplicates (2)
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