VTK  9.3.1
vtkSMPThreadPool.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-License-Identifier: BSD-3-Clause
3 // .NAME vtkSMPThreadPool - A thread pool implementation using std::thread
4 //
5 // .SECTION Description
6 // vtkSMPThreadPool class creates a thread pool of std::thread, the number
7 // of thread must be specified at the initialization of the class.
8 // The DoJob() method is used attributes the job to a free thread, if all
9 // threads are working, the job is kept in a queue. Note that vtkSMPThreadPool
10 // destructor joins threads and finish the jobs in the queue.
11 
12 #ifndef vtkSMPThreadPool_h
13 #define vtkSMPThreadPool_h
14 
15 #include "vtkCommonCoreModule.h" // For export macro
16 #include "vtkSystemIncludes.h"
17 
18 #include <atomic> // For std::atomic
19 #include <functional> // For std::function
20 #include <mutex> // For std::unique_lock
21 #include <thread> // For std::thread
22 #include <vector> // For std::vector
23 
24 namespace vtk
25 {
26 namespace detail
27 {
28 namespace smp
29 {
30 VTK_ABI_NAMESPACE_BEGIN
31 
40 class VTKCOMMONCORE_EXPORT vtkSMPThreadPool
41 {
42  // Internal data structures
43  struct ThreadJob;
44  struct ThreadData;
45  struct ProxyThreadData;
46  struct ProxyData;
47 
48 public:
59  class VTKCOMMONCORE_EXPORT Proxy final
60  {
61  public:
67  ~Proxy();
68  Proxy(const Proxy&) = delete;
69  Proxy& operator=(const Proxy&) = delete;
70  Proxy(Proxy&&) noexcept;
71  Proxy& operator=(Proxy&&) noexcept;
72 
79  void Join();
80 
84  void DoJob(std::function<void()> job);
85 
89  std::vector<std::reference_wrapper<std::thread>> GetThreads() const;
90 
94  bool IsTopLevel() const noexcept;
95 
96  private:
97  friend class vtkSMPThreadPool; // Only the thread pool can construct this object
98 
99  Proxy(std::unique_ptr<ProxyData>&& data);
100 
101  std::unique_ptr<ProxyData> Data;
102  };
103 
105  ~vtkSMPThreadPool();
106  vtkSMPThreadPool(const vtkSMPThreadPool&) = delete;
107  vtkSMPThreadPool& operator=(const vtkSMPThreadPool&) = delete;
108 
125  Proxy AllocateThreads(std::size_t threadCount = 0);
126 
130  static constexpr std::size_t ExternalThreadID = 1;
131 
139  std::size_t GetThreadId() const noexcept;
140 
144  bool IsParallelScope() const noexcept;
145 
149  bool GetSingleThread() const;
150 
154  std::size_t ThreadCount() const noexcept;
155 
156 private:
157  // static because also used by proxy
158  static void RunJob(ThreadData& data, std::size_t jobIndex, std::unique_lock<std::mutex>& lock);
159 
160  ThreadData* GetCallerThreadData() const noexcept;
161 
162  std::thread MakeThread();
163  void FillThreadsForNestedProxy(ProxyData* proxy, std::size_t maxCount);
164  std::size_t GetNextThreadId() noexcept;
165 
166  std::atomic<bool> Initialized{};
167  std::atomic<bool> Joining{};
168  std::vector<std::unique_ptr<ThreadData>> Threads; // Thread pool, fixed size
169  std::atomic<std::size_t> NextProxyThreadId{ 1 };
170 
171 public:
172  static vtkSMPThreadPool& GetInstance();
173 };
174 
175 VTK_ABI_NAMESPACE_END
176 } // namespace smp
177 } // namespace detail
178 } // namespace vtk
179 
180 #endif
181 /* VTK-HeaderTest-Exclude: vtkSMPThreadPool.h */
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
Proxy class used to submit work to the thread pool.
Internal thread pool implementation used in SMP functions.