Orrery
A GPU-accelerated N-body gravitational simulator
Toggle main menu visibility
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
35
#include "
orrery/backend/cpu_topology.hpp
"
36
#include "
orrery/core/function_ref.hpp
"
37
38
namespace
orrery::backend {
39
41
class
ThreadPool
{
42
public
:
44
enum class
Affinity
: std::uint8_t {
51
kUnpinned
,
57
kPinned
,
58
};
59
61
using
WorkerBody
=
core::FunctionRef
<void(
unsigned
)>;
62
69
explicit
ThreadPool
(
unsigned
worker_count = 0,
Affinity
affinity =
Affinity::kUnpinned
);
70
72
~ThreadPool
();
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
107
private:
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
orrery::backend::ThreadPool::Affinity
Affinity
Whether workers are tied to a particular logical processor.
Definition
thread_pool.hpp:44
orrery::backend::ThreadPool::Affinity::kPinned
@ kPinned
Tie worker w to logical processor w.
Definition
thread_pool.hpp:57
orrery::backend::ThreadPool::Affinity::kUnpinned
@ kUnpinned
Let the operating system place the threads.
Definition
thread_pool.hpp:51
orrery::backend::ThreadPool::core_class
CoreClass core_class(unsigned worker) const noexcept
The class of core worker runs on, or kUnknown when unpinned or undiscoverable.
orrery::backend::ThreadPool::default_worker_count
static unsigned default_worker_count() noexcept
One worker per logical processor, and never zero.
orrery::backend::ThreadPool::dispatch
void dispatch(WorkerBody body)
Run body(worker) once on every worker and return when all have returned.
orrery::backend::ThreadPool::~ThreadPool
~ThreadPool()
Stop the workers and join them.
orrery::backend::ThreadPool::WorkerBody
core::FunctionRef< void(unsigned)> WorkerBody
What each worker is asked to do, given its own index.
Definition
thread_pool.hpp:61
orrery::backend::ThreadPool::ThreadPool
ThreadPool(unsigned worker_count=0, Affinity affinity=Affinity::kUnpinned)
Start worker_count threads, or one per logical processor if zero.
orrery::core::FunctionRef
Definition
function_ref.hpp:36
cpu_topology.hpp
Which logical processors this machine has, and which of them are fast.
orrery::backend::CoreClass
CoreClass
What kind of core a logical processor belongs to.
Definition
cpu_topology.hpp:47
function_ref.hpp
A non-owning reference to something callable.
orrery
backend
thread_pool.hpp
Generated by
1.17.0