Orrery
A GPU-accelerated N-body gravitational simulator
Loading...
Searching...
No Matches
thread_pool.hpp
Go to the documentation of this file.
1#pragma once
2
28
29#include <condition_variable>
30#include <cstdint>
31#include <mutex>
32#include <thread>
33#include <vector>
34
37
38namespace orrery::backend {
39
42public:
44 enum class Affinity : std::uint8_t {
58 };
59
61 using WorkerBody = core::FunctionRef<void(unsigned)>;
62
69 explicit ThreadPool(unsigned worker_count = 0, Affinity affinity = Affinity::kUnpinned);
70
73
74 // A pool owns running threads that hold a pointer to it, so it cannot be
75 // copied and cannot move out from under them.
76 ThreadPool(const ThreadPool&) = delete;
77 ThreadPool& operator=(const ThreadPool&) = delete;
78 ThreadPool(ThreadPool&&) = delete;
79 ThreadPool& operator=(ThreadPool&&) = delete;
80
89 void dispatch(WorkerBody body);
90
91 [[nodiscard]] unsigned worker_count() const noexcept {
92 return static_cast<unsigned>(threads_.size());
93 }
94
95 [[nodiscard]] Affinity affinity() const noexcept { return affinity_; }
96
99 [[nodiscard]] CoreClass core_class(unsigned worker) const noexcept;
100
105 [[nodiscard]] static unsigned default_worker_count() noexcept;
106
107private:
108 void worker_loop(unsigned worker) noexcept;
109
110 std::mutex mutex_;
111
113 std::condition_variable work_available_;
114
116 std::condition_variable work_complete_;
117
119 std::condition_variable worker_started_;
120
123 const WorkerBody* body_{nullptr};
124
129 std::uint64_t generation_{0};
130
132 unsigned pending_{0};
133
135 unsigned starting_{0};
136
137 bool stopping_{false};
138
139 Affinity affinity_{Affinity::kUnpinned};
140
143 std::vector<unsigned> pin_targets_;
144
153 std::vector<CoreClass> core_classes_;
154
157 std::vector<std::thread> threads_;
158};
159
160} // namespace orrery::backend
Affinity
Whether workers are tied to a particular logical processor.
Definition thread_pool.hpp:44
@ kPinned
Tie worker w to logical processor w.
Definition thread_pool.hpp:57
@ kUnpinned
Let the operating system place the threads.
Definition thread_pool.hpp:51
CoreClass core_class(unsigned worker) const noexcept
The class of core worker runs on, or kUnknown when unpinned or undiscoverable.
static unsigned default_worker_count() noexcept
One worker per logical processor, and never zero.
void dispatch(WorkerBody body)
Run body(worker) once on every worker and return when all have returned.
~ThreadPool()
Stop the workers and join them.
core::FunctionRef< void(unsigned)> WorkerBody
What each worker is asked to do, given its own index.
Definition thread_pool.hpp:61
ThreadPool(unsigned worker_count=0, Affinity affinity=Affinity::kUnpinned)
Start worker_count threads, or one per logical processor if zero.
Definition function_ref.hpp:36
Which logical processors this machine has, and which of them are fast.
CoreClass
What kind of core a logical processor belongs to.
Definition cpu_topology.hpp:47
A non-owning reference to something callable.