VTK  9.4.20241118
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
24namespace vtk
25{
26namespace detail
27{
28namespace smp
29{
30VTK_ABI_NAMESPACE_BEGIN
31
40class VTKCOMMONCORE_EXPORT vtkSMPThreadPool
41{
42 // Internal data structures
43 struct ThreadJob;
44 struct ThreadData;
45 struct ProxyThreadData;
46 struct ProxyData;
47
48public:
59 class VTKCOMMONCORE_EXPORT Proxy final
60 {
61 public:
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
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
156private:
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
171public:
173};
174
175VTK_ABI_NAMESPACE_END
176} // namespace smp
177} // namespace detail
178} // namespace vtk
179
180#endif
181/* VTK-HeaderTest-Exclude: vtkSMPThreadPool.h */
Proxy class used to submit work to the thread pool.
Proxy & operator=(const Proxy &)=delete
Internal thread pool implementation used in SMP functions.
static vtkSMPThreadPool & GetInstance()
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.