Libosmium
Fast and flexible C++ library for working with OpenStreetMap data
Toggle main menu visibility
Loading...
Searching...
No Matches
include
osmium
thread
pool.hpp
Go to the documentation of this file.
1
#ifndef OSMIUM_THREAD_POOL_HPP
2
#define OSMIUM_THREAD_POOL_HPP
3
4
/*
5
6
This file is part of Osmium (https://osmcode.org/libosmium).
7
8
Copyright 2013-2026 Jochen Topf <jochen@topf.org> and others (see README).
9
10
Boost Software License - Version 1.0 - August 17th, 2003
11
12
Permission is hereby granted, free of charge, to any person or organization
13
obtaining a copy of the software and accompanying documentation covered by
14
this license (the "Software") to use, reproduce, display, distribute,
15
execute, and transmit the Software, and to prepare derivative works of the
16
Software, and to permit third-parties to whom the Software is furnished to
17
do so, all subject to the following:
18
19
The copyright notices in the Software and this entire statement, including
20
the above license grant, this restriction and the following disclaimer,
21
must be included in all copies of the Software, in whole or in part, and
22
all derivative works of the Software, unless such copies or derivative
23
works are solely in the form of machine-executable object code generated by
24
a source language processor.
25
26
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
29
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
30
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
31
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
32
DEALINGS IN THE SOFTWARE.
33
34
*/
35
36
#include <
osmium/thread/function_wrapper.hpp
>
37
#include <
osmium/thread/queue.hpp
>
38
#include <
osmium/thread/util.hpp
>
39
#include <
osmium/util/config.hpp
>
40
41
#include <cstddef>
42
#include <future>
43
#include <thread>
44
#include <type_traits>
45
#include <utility>
46
#include <vector>
47
48
namespace
osmium
{
49
53
namespace
thread
{
54
55
namespace
detail {
56
57
// Maximum number of allowed pool threads (just to keep the user
58
// from setting something silly).
59
enum
{
60
max_pool_threads = 32
61
};
62
63
inline
int
get_pool_size(
int
num_threads,
int
user_setting,
unsigned
hardware_concurrency) {
64
if
(num_threads == 0) {
65
num_threads = user_setting ? user_setting : -2;
66
}
67
68
if
(num_threads < 0) {
69
num_threads +=
static_cast<
int
>
(hardware_concurrency);
70
}
71
72
if
(num_threads < 1) {
73
num_threads = 1;
74
}
else
if
(num_threads > max_pool_threads) {
75
num_threads = max_pool_threads;
76
}
77
78
return
num_threads;
79
}
80
81
inline
std::size_t get_work_queue_size() noexcept {
82
return
osmium::config::get_max_queue_size
(
"WORK"
, 10);
83
}
84
85
}
// namespace detail
86
90
class
Pool
{
91
96
class
thread_joiner
{
97
98
std::vector<std::thread>&
m_threads
;
99
100
public
:
101
102
explicit
thread_joiner
(std::vector<std::thread>& threads) :
103
m_threads
(threads) {
104
}
105
106
thread_joiner
(
const
thread_joiner
&) =
delete
;
107
thread_joiner
&
operator=
(
const
thread_joiner
&) =
delete
;
108
109
thread_joiner
(
thread_joiner
&&) =
delete
;
110
thread_joiner
&
operator=
(
thread_joiner
&&) =
delete
;
111
112
~thread_joiner
() {
113
for
(
auto
&
thread
:
m_threads
) {
114
if
(
thread
.joinable()) {
115
thread
.join();
116
}
117
}
118
}
119
120
};
// class thread_joiner
121
122
osmium::thread::Queue<function_wrapper>
m_work_queue
;
123
std::vector<std::thread>
m_threads
;
124
thread_joiner
m_joiner
;
125
int
m_num_threads
;
126
127
void
worker_thread
() {
128
osmium::thread::set_thread_name
(
"_osmium_worker"
);
129
while
(
true
) {
130
function_wrapper
task;
131
m_work_queue
.wait_and_pop(task);
132
if
(task && task()) {
133
// The called tasks returns true only when the
134
// worker thread should shut down.
135
return
;
136
}
137
}
138
}
139
140
public
:
141
142
enum
{
143
default_num_threads
= 0
144
};
145
146
enum
{
147
default_queue_size
= 0U
148
};
149
165
explicit
Pool
(
int
num_threads
=
default_num_threads
, std::size_t max_queue_size =
default_queue_size
) :
166
m_work_queue
(max_queue_size > 0 ? max_queue_size :
detail
::get_work_queue_size(),
"work"
),
167
m_joiner
(
m_threads
),
168
m_num_threads
(
detail
::get_pool_size(
num_threads
,
osmium
::
config
::get_pool_threads(),
std
::
thread
::hardware_concurrency())) {
169
170
try
{
171
for
(
int
i = 0; i <
m_num_threads
; ++i) {
172
m_threads
.emplace_back(&
Pool::worker_thread
,
this
);
173
}
174
}
catch
(...) {
175
shutdown_all_workers
();
176
throw
;
177
}
178
}
179
186
static
Pool
&
default_instance
() {
187
static
Pool
pool{};
188
return
pool;
189
}
190
191
void
shutdown_all_workers
() {
192
for
(
int
i = 0; i <
m_num_threads
; ++i) {
193
// The special function wrapper makes a worker shut down.
194
m_work_queue
.push(
function_wrapper
{0});
195
}
196
}
197
198
Pool
(
const
Pool
&) =
delete
;
199
Pool
&
operator=
(
const
Pool
&) =
delete
;
200
201
Pool
(
Pool
&&) =
delete
;
202
Pool
&
operator=
(
Pool
&&) =
delete
;
203
204
~Pool
() {
205
shutdown_all_workers
();
206
}
207
208
int
num_threads
() const noexcept {
209
return
m_num_threads
;
210
}
211
212
std::size_t
queue_size
()
const
{
213
return
m_work_queue
.size();
214
}
215
216
bool
queue_empty
()
const
{
217
return
m_work_queue
.empty();
218
}
219
220
#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
221
// std::result_of is deprecated in C++17 and removed in C++20,
222
// so we use std::invoke_result_t.
223
template
<
typename
TFunction>
224
using
submit_func_result_type
= std::invoke_result_t<TFunction>;
225
#else
226
// For C++11 and C++14
227
template
<
typename
TFunction>
228
using
submit_func_result_type
= std::result_of_t<TFunction()>;
229
#endif
230
231
template
<
typename
TFunction>
232
std::future<submit_func_result_type<TFunction>>
submit
(TFunction&& func) {
233
std::packaged_task<submit_func_result_type<TFunction>()> task{std::forward<TFunction>(func)};
234
std::future<submit_func_result_type<TFunction>> future_result{task.get_future()};
235
m_work_queue
.push(std::move(task));
236
237
return
future_result;
238
}
239
240
};
// class Pool
241
242
}
// namespace thread
243
244
}
// namespace osmium
245
246
#endif
// OSMIUM_THREAD_POOL_HPP
osmium::thread::Pool::thread_joiner
Definition
pool.hpp:96
osmium::thread::Pool::thread_joiner::thread_joiner
thread_joiner(std::vector< std::thread > &threads)
Definition
pool.hpp:102
osmium::thread::Pool::thread_joiner::thread_joiner
thread_joiner(thread_joiner &&)=delete
osmium::thread::Pool::thread_joiner::m_threads
std::vector< std::thread > & m_threads
Definition
pool.hpp:98
osmium::thread::Pool::thread_joiner::thread_joiner
thread_joiner(const thread_joiner &)=delete
osmium::thread::Pool::thread_joiner::operator=
thread_joiner & operator=(thread_joiner &&)=delete
osmium::thread::Pool::thread_joiner::operator=
thread_joiner & operator=(const thread_joiner &)=delete
osmium::thread::Pool::thread_joiner::~thread_joiner
~thread_joiner()
Definition
pool.hpp:112
osmium::thread::Pool::submit_func_result_type
std::result_of_t< TFunction()> submit_func_result_type
Definition
pool.hpp:228
osmium::thread::Pool::shutdown_all_workers
void shutdown_all_workers()
Definition
pool.hpp:191
osmium::thread::Pool::m_threads
std::vector< std::thread > m_threads
Definition
pool.hpp:123
osmium::thread::Pool::~Pool
~Pool()
Definition
pool.hpp:204
osmium::thread::Pool::Pool
Pool(int num_threads=default_num_threads, std::size_t max_queue_size=default_queue_size)
Definition
pool.hpp:165
osmium::thread::Pool::Pool
Pool(Pool &&)=delete
osmium::thread::Pool::queue_size
std::size_t queue_size() const
Definition
pool.hpp:212
osmium::thread::Pool::default_queue_size
@ default_queue_size
Definition
pool.hpp:147
osmium::thread::Pool::submit
std::future< submit_func_result_type< TFunction > > submit(TFunction &&func)
Definition
pool.hpp:232
osmium::thread::Pool::default_instance
static Pool & default_instance()
Definition
pool.hpp:186
osmium::thread::Pool::Pool
Pool(const Pool &)=delete
osmium::thread::Pool::operator=
Pool & operator=(Pool &&)=delete
osmium::thread::Pool::m_work_queue
osmium::thread::Queue< function_wrapper > m_work_queue
Definition
pool.hpp:122
osmium::thread::Pool::default_num_threads
@ default_num_threads
Definition
pool.hpp:143
osmium::thread::Pool::m_joiner
thread_joiner m_joiner
Definition
pool.hpp:124
osmium::thread::Pool::queue_empty
bool queue_empty() const
Definition
pool.hpp:216
osmium::thread::Pool::worker_thread
void worker_thread()
Definition
pool.hpp:127
osmium::thread::Pool::m_num_threads
int m_num_threads
Definition
pool.hpp:125
osmium::thread::Pool::operator=
Pool & operator=(const Pool &)=delete
osmium::thread::Pool::num_threads
int num_threads() const noexcept
Definition
pool.hpp:208
osmium::thread::Queue
Definition
queue.hpp:57
osmium::thread::function_wrapper
Definition
function_wrapper.hpp:48
config.hpp
function_wrapper.hpp
detail
Definition
attr.hpp:342
osmium::config
Definition
config.hpp:60
osmium::config::get_max_queue_size
std::size_t get_max_queue_size(const char *queue_name, const std::size_t default_value) noexcept
Definition
config.hpp:83
osmium::thread
Threading-related low-level code.
Definition
function_wrapper.hpp:41
osmium::thread::set_thread_name
void set_thread_name(const char *name) noexcept
Definition
util.hpp:78
osmium
Namespace for everything in the Osmium library.
Definition
assembler.hpp:53
std
Definition
location.hpp:654
queue.hpp
util.hpp
Generated by
1.17.0