This source file includes following definitions.
- BOOST_AUTO_TEST_SUITE
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_SUITE_END
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_CASE_TEMPLATE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include "stdafx.h"
22
23 #define BOOST_TEST_MODULE libjmmcg_tests
24 #include <boost/test/included/unit_test.hpp>
25
26 #include <boost/test/test_case_template.hpp>
27 #include <boost/mpl/list.hpp>
28
29 #include "core/thread_pool_sequential.hpp"
30 #include "core/thread_pool_master.hpp"
31 #include "core/thread_pool_workers.hpp"
32
33 #include <boost/bind.hpp>
34
35 using namespace jmmcg;
36 using namespace jmmcg::ppd;
37
38 template<class Db, pool_traits::size_mode_t Sz, generic_traits::return_data Jn, class Mdl, template<class> class CFG=no_control_flow_graph, unsigned int PoolSize=0, unsigned int GSSk=1>
39 struct fifo_queue_t {
40 typedef pool_aspects<
41 Jn,
42 platform_api,
43 Mdl,
44 pool_traits::normal_fifo,
45 std::less,
46 GSSk,
47 basic_statistics,
48 CFG
49 > thread_pool_traits;
50
51 typedef thread_pool<Db, Sz, thread_pool_traits> pool_type;
52
53 static const typename pool_type::pool_type::size_type pool_size=PoolSize;
54 };
55
56 template<class Db, pool_traits::size_mode_t Sz, generic_traits::return_data Jn, class Mdl, template<class> class CFG, unsigned int PoolSize, unsigned int GSSk>
57 const typename fifo_queue_t<Db, Sz, Jn, Mdl, CFG, PoolSize, GSSk>::pool_type::pool_type::size_type fifo_queue_t<Db, Sz, Jn, Mdl, CFG, PoolSize, GSSk>::pool_size;
58
59 template<class Db, pool_traits::size_mode_t Sz, generic_traits::return_data Jn, class Mdl, template<class> class CFG=no_control_flow_graph, unsigned int PoolSize=0, unsigned int GSSk=1>
60 struct lifo_queue_t {
61 typedef pool_aspects<
62 Jn,
63 platform_api,
64 Mdl,
65 pool_traits::normal_lifo,
66 std::less,
67 GSSk,
68 basic_statistics,
69 CFG
70 > thread_pool_traits;
71
72 typedef thread_pool<Db, Sz, thread_pool_traits> pool_type;
73
74 static const typename pool_type::pool_type::size_type pool_size=PoolSize;
75 };
76
77 template<class Db, pool_traits::size_mode_t Sz, generic_traits::return_data Jn, class Mdl, template<class> class CFG, unsigned int PoolSize, unsigned int GSSk>
78 const typename lifo_queue_t<Db, Sz, Jn, Mdl, CFG, PoolSize, GSSk>::pool_type::pool_type::size_type lifo_queue_t<Db, Sz, Jn, Mdl, CFG, PoolSize, GSSk>::pool_size;
79
80 typedef boost::mpl::list<
81 fifo_queue_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::sequential, generic_traits::return_data::joinable, sequential_mode>,
82 fifo_queue_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::sequential, generic_traits::return_data::joinable, sequential_mode, control_flow_graph>,
83 fifo_queue_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::fixed_size, generic_traits::return_data::joinable, heavyweight_threading, no_control_flow_graph, 1>,
84 fifo_queue_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::fixed_size, generic_traits::return_data::joinable, heavyweight_threading, control_flow_graph, 1>,
85 fifo_queue_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::fixed_size, generic_traits::return_data::joinable, heavyweight_threading, no_control_flow_graph, 2>,
86 fifo_queue_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::fixed_size, generic_traits::return_data::joinable, heavyweight_threading, control_flow_graph, 2>,
87 lifo_queue_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::sequential, generic_traits::return_data::joinable, sequential_mode>,
88 lifo_queue_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::sequential, generic_traits::return_data::joinable, sequential_mode, control_flow_graph>,
89 lifo_queue_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::fixed_size, generic_traits::return_data::joinable, heavyweight_threading, no_control_flow_graph, 1>,
90 lifo_queue_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::fixed_size, generic_traits::return_data::joinable, heavyweight_threading, control_flow_graph, 1>,
91 lifo_queue_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::fixed_size, generic_traits::return_data::joinable, heavyweight_threading, no_control_flow_graph, 2>,
92 lifo_queue_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::fixed_size, generic_traits::return_data::joinable, heavyweight_threading, control_flow_graph, 2>
93 > finite_test_types;
94
95 typedef boost::mpl::list<
96 fifo_queue_t<pool_traits::work_distribution_mode_t::one_thread_distributes<>, pool_traits::size_mode_t::sequential, generic_traits::return_data::joinable, sequential_mode>,
97 fifo_queue_t<pool_traits::work_distribution_mode_t::one_thread_distributes<>, pool_traits::size_mode_t::sequential, generic_traits::return_data::joinable, sequential_mode, control_flow_graph>,
98 fifo_queue_t<pool_traits::work_distribution_mode_t::one_thread_distributes<>, pool_traits::size_mode_t::infinite, generic_traits::return_data::joinable, heavyweight_threading>,
99 fifo_queue_t<pool_traits::work_distribution_mode_t::one_thread_distributes<>, pool_traits::size_mode_t::infinite, generic_traits::return_data::joinable, heavyweight_threading, control_flow_graph>,
100 lifo_queue_t<pool_traits::work_distribution_mode_t::one_thread_distributes<>, pool_traits::size_mode_t::sequential, generic_traits::return_data::joinable, sequential_mode>,
101 lifo_queue_t<pool_traits::work_distribution_mode_t::one_thread_distributes<>, pool_traits::size_mode_t::sequential, generic_traits::return_data::joinable, sequential_mode, control_flow_graph>,
102 lifo_queue_t<pool_traits::work_distribution_mode_t::one_thread_distributes<>, pool_traits::size_mode_t::infinite, generic_traits::return_data::joinable, heavyweight_threading>,
103 lifo_queue_t<pool_traits::work_distribution_mode_t::one_thread_distributes<>, pool_traits::size_mode_t::infinite, generic_traits::return_data::joinable, heavyweight_threading, control_flow_graph>
104 > infinite_test_types;
105
106
107
108 struct res_t {
109 long i;
110 };
111
112 struct work_type {
113 typedef res_t result_type;
114
115 int i_;
116
117 explicit work_type(const int i)
118 : i_(i) {
119 }
120 void __fastcall process(result_type &r) {
121 r.i=i_<<1;
122 }
123 void __fastcall mutate(result_type &r) {
124 process(r);
125 }
126
127 bool __fastcall operator<(work_type const &i) const {
128 return i_<i.i_;
129 }
130 };
131
132 struct work_type_simple {
133 int i_;
134
135 work_type_simple(const int i)
136 : i_(i) {
137 }
138 void __fastcall process(res_t &r) {
139 r.i=i_<<1;
140 }
141
142 bool __fastcall operator<(work_type_simple const &i) const {
143 return i_<i.i_;
144 }
145 };
146
147 struct bool_work_type {
148 typedef bool result_type;
149
150 int i_;
151
152 explicit bool_work_type(const int i)
153 : i_(i) {
154 }
155 void __fastcall process(result_type &r) const {
156 r=static_cast<bool>(i_);
157 }
158 bool __fastcall operator<(bool_work_type const &) const {
159 return true;
160 }
161 };
162
163 template<generic_traits::api_type API, typename Mdl>
164 struct horizontal_work_type {
165 typedef void result_type;
166
167 bool &release;
168
169 explicit horizontal_work_type(bool &r) noexcept(true)
170 : release(r) {
171 }
172
173 void __fastcall process() noexcept(false) {
174 while (!release) {
175 api_threading_traits<API, Mdl>::sleep(10);
176 }
177 }
178 bool __fastcall operator<(horizontal_work_type const &) const {
179 return true;
180 }
181 };
182 template<generic_traits::api_type API>
183 struct horizontal_work_type<API, sequential_mode> {
184 typedef void result_type;
185
186 bool &release;
187
188 explicit horizontal_work_type(bool &r) noexcept(true)
189 : release(r) {
190 }
191
192 void __fastcall process() noexcept(true) {
193 }
194 bool __fastcall operator<(horizontal_work_type const &) const {
195 return true;
196 }
197 };
198
199 template<generic_traits::api_type API, typename Mdl>
200 struct horizontal_work_type_rel {
201 typedef void result_type;
202
203 bool &release;
204
205 explicit horizontal_work_type_rel(bool &r) noexcept(true)
206 : release(r) {}
207
208 void __fastcall process() noexcept(true) {
209 release=true;
210 }
211 bool __fastcall operator<(horizontal_work_type_rel const &) const {
212 return true;
213 }
214 };
215
216 BOOST_AUTO_TEST_SUITE(thread_pool_tests)
217
218 BOOST_AUTO_TEST_SUITE(joinable)
219
220 BOOST_AUTO_TEST_SUITE(finite)
221
222 BOOST_AUTO_TEST_SUITE(wait_dataflow)
223
224 BOOST_AUTO_TEST_CASE_TEMPLATE(add_one_work, T, finite_test_types) {
225 typedef typename T::pool_type pool_type;
226 typedef typename pool_type::joinable joinable;
227
228 pool_type pool(T::pool_size);
229 auto const &context=pool<<joinable()<<work_type_simple(1);
230 BOOST_CHECK_EQUAL(context->i, 2);
231 BOOST_CHECK_EQUAL(pool.statistics().total_work_added(), 1);
232 BOOST_CHECK_GE(pool.statistics().total_vertical_work().total(), 0);
233 BOOST_CHECK_LE(pool.statistics().total_vertical_work().total(), 1);
234 BOOST_CHECK_GE(pool.statistics().total_hrz_work().total(), 0);
235 BOOST_CHECK_LE(pool.statistics().total_hrz_work().total(), 1);
236 BOOST_CHECK_GE(pool.statistics().total_work_added(), pool.statistics().total_vertical_work().total()+pool.statistics().total_hrz_work().total());
237 BOOST_CHECK_EQUAL(pool.min_time(context), 0U);
238 BOOST_CHECK_EQUAL(pool.min_processors(context), 0U);
239 std::cout<<pool.statistics()<<std::endl;
240 }
241
242 BOOST_AUTO_TEST_CASE_TEMPLATE(add_two_work, T, finite_test_types) {
243 typedef typename T::pool_type pool_type;
244 typedef typename pool_type::joinable joinable;
245
246 pool_type pool(T::pool_size);
247 auto const &context=pool<<joinable()<<work_type_simple(1);
248 auto const &context2=pool<<joinable()<<work_type_simple(3);
249 BOOST_CHECK_EQUAL(context->i, 2);
250 BOOST_CHECK_EQUAL(context2->i, 6);
251 BOOST_CHECK_EQUAL(pool.statistics().total_work_added(), 2);
252 BOOST_CHECK_GE(pool.statistics().total_vertical_work().total(), 0);
253 BOOST_CHECK_LE(pool.statistics().total_vertical_work().total(), 2);
254 BOOST_CHECK_GE(pool.statistics().total_hrz_work().total(), 0);
255 BOOST_CHECK_LE(pool.statistics().total_hrz_work().total(), 2);
256 BOOST_CHECK_GE(pool.statistics().total_work_added(), pool.statistics().total_vertical_work().total()+pool.statistics().total_hrz_work().total());
257 BOOST_CHECK_EQUAL(pool.min_time(context), 0U);
258 BOOST_CHECK_EQUAL(pool.min_processors(context), 0U);
259 std::cout<<pool.statistics()<<std::endl;
260 }
261
262 BOOST_AUTO_TEST_CASE_TEMPLATE(horizontal_threading, T, finite_test_types) {
263 typedef horizontal_work_type<T::thread_pool_traits::os_traits::thread_traits::api_params_type::api_type, typename T::thread_pool_traits::os_traits::thread_traits::model_type> hrz_wk_t;
264 typedef horizontal_work_type_rel<T::thread_pool_traits::os_traits::thread_traits::api_params_type::api_type, typename T::thread_pool_traits::os_traits::thread_traits::model_type> hrz_wk_rel_t;
265 typedef typename T::pool_type pool_type;
266 typedef typename pool_type::joinable joinable;
267
268 pool_type pool(T::pool_size);
269 bool release=false;
270 hrz_wk_t hz(release);
271 hrz_wk_rel_t hz_rel(release);
272 auto const &context=pool<<joinable()<<hz;
273 auto const &context_rel=pool<<joinable()<<hz_rel;
274 *context;
275 *context_rel;
276 BOOST_CHECK_EQUAL(pool.statistics().total_work_added(), 2);
277 BOOST_CHECK_GE(pool.statistics().total_vertical_work().total(), 0);
278 BOOST_CHECK_LE(pool.statistics().total_vertical_work().total(), 2);
279 BOOST_CHECK_GE(pool.statistics().total_hrz_work().total(), 0);
280 BOOST_CHECK_LE(pool.statistics().total_hrz_work().total(), 2);
281 BOOST_CHECK_GE(pool.statistics().total_work_added(), pool.statistics().total_vertical_work().total()+pool.statistics().total_hrz_work().total());
282 BOOST_CHECK_EQUAL(pool.min_time(context), 0U);
283 BOOST_CHECK_EQUAL(pool.min_processors(context), 0U);
284 std::cout<<pool.statistics()<<std::endl;
285 }
286
287 BOOST_AUTO_TEST_CASE_TEMPLATE(unary_fn, T, finite_test_types) {
288 typedef typename T::pool_type pool_type;
289
290 pool_type pool(T::pool_size);
291 auto const &context=pool.unary_fun(bool_work_type(0), std::logical_not<bool_work_type::result_type>());
292 BOOST_CHECK_EQUAL(*context, true);
293 BOOST_CHECK_EQUAL(pool.statistics().total_work_added(), 2);
294 BOOST_CHECK_GE(pool.statistics().total_vertical_work().total(), 0);
295 BOOST_CHECK_LE(pool.statistics().total_vertical_work().total(), 2);
296 BOOST_CHECK_GE(pool.statistics().total_hrz_work().total(), 0);
297 BOOST_CHECK_LE(pool.statistics().total_hrz_work().total(), 2);
298 BOOST_CHECK_GE(pool.statistics().total_work_added(), pool.statistics().total_vertical_work().total()+pool.statistics().total_hrz_work().total());
299 BOOST_CHECK_EQUAL(pool.min_time(context), 0U);
300 BOOST_CHECK_EQUAL(pool.min_processors(context), 0U);
301 std::cout<<pool.statistics()<<std::endl;
302 }
303
304 BOOST_AUTO_TEST_CASE_TEMPLATE(logical_and, T, finite_test_types) {
305 typedef typename T::pool_type pool_type;
306
307 pool_type pool(T::pool_size);
308 BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
309 auto const &context=pool.logical_and(bool_work_type(1), bool_work_type(2));
310 BOOST_CHECK_EQUAL(*context, true);
311 BOOST_CHECK_EQUAL(pool.statistics().total_work_added(), 3);
312 BOOST_CHECK_GE(pool.statistics().total_vertical_work().total(), 0);
313 BOOST_CHECK_LE(pool.statistics().total_vertical_work().total(), 3);
314 BOOST_CHECK_GE(pool.statistics().total_hrz_work().total(), 0);
315 BOOST_CHECK_LE(pool.statistics().total_hrz_work().total(), 3);
316 BOOST_CHECK_GE(pool.statistics().total_work_added(), pool.statistics().total_vertical_work().total()+pool.statistics().total_hrz_work().total());
317 BOOST_CHECK_EQUAL(pool.min_time(context), 0U);
318 BOOST_CHECK_EQUAL(pool.min_processors(context), 0U);
319 std::cout<<pool.statistics()<<std::endl;
320 }
321
322 BOOST_AUTO_TEST_SUITE_END()
323
324 BOOST_AUTO_TEST_SUITE_END()
325
326 BOOST_AUTO_TEST_SUITE(infinite)
327
328 BOOST_AUTO_TEST_SUITE(wait_dataflow)
329
330 BOOST_AUTO_TEST_CASE_TEMPLATE(add_one_work, T, infinite_test_types) {
331 typedef typename T::pool_type pool_type;
332 typedef typename pool_type::joinable joinable;
333
334 pool_type pool;
335 auto const &context=pool<<joinable()<<work_type_simple(1);
336 BOOST_CHECK_EQUAL(context->i, 2);
337 BOOST_CHECK_EQUAL(pool.statistics().total_work_added(), 1);
338
339 BOOST_CHECK_GE(pool.statistics().total_vertical_work().total(), 0);
340 BOOST_CHECK_LE(pool.statistics().total_vertical_work().total(), 1);
341 BOOST_CHECK_EQUAL(pool.statistics().total_hrz_work().total(), 0);
342 BOOST_CHECK_GE(pool.statistics().total_work_added(), pool.statistics().total_vertical_work().total()+pool.statistics().total_hrz_work().total());
343 BOOST_CHECK_EQUAL(pool.min_time(context), 0U);
344 BOOST_CHECK_EQUAL(pool.min_processors(context), 0U);
345 std::cout<<pool.statistics()<<std::endl;
346 }
347
348 BOOST_AUTO_TEST_CASE_TEMPLATE(add_two_work, T, infinite_test_types) {
349 typedef typename T::pool_type pool_type;
350 typedef typename pool_type::joinable joinable;
351
352 pool_type pool;
353 auto const &context=pool<<joinable()<<work_type_simple(1);
354 auto const &context2=pool<<joinable()<<work_type_simple(3);
355 BOOST_CHECK_EQUAL(context->i, 2);
356 BOOST_CHECK_EQUAL(context2->i, 6);
357 BOOST_CHECK_EQUAL(pool.statistics().total_work_added(), 2);
358
359 BOOST_CHECK_GE(pool.statistics().total_vertical_work().total(), 0);
360 BOOST_CHECK_LE(pool.statistics().total_vertical_work().total(), 2);
361 BOOST_CHECK_EQUAL(pool.statistics().total_hrz_work().total(), 0);
362 BOOST_CHECK_GE(pool.statistics().total_work_added(), pool.statistics().total_vertical_work().total()+pool.statistics().total_hrz_work().total());
363 BOOST_CHECK_EQUAL(pool.min_time(context), 0U);
364 BOOST_CHECK_EQUAL(pool.min_processors(context), 0U);
365 std::cout<<pool.statistics()<<std::endl;
366 }
367
368 BOOST_AUTO_TEST_CASE_TEMPLATE(unary_fn, T, infinite_test_types) {
369 typedef typename T::pool_type pool_type;
370
371 pool_type pool;
372 auto const &context=pool.unary_fun(bool_work_type(1),std::logical_not<bool_work_type::result_type>());
373 BOOST_CHECK_EQUAL(*context, false);
374 BOOST_CHECK_EQUAL(pool.statistics().total_work_added(), 2);
375
376 BOOST_CHECK_GE(pool.statistics().total_vertical_work().total(), 0);
377 BOOST_CHECK_LE(pool.statistics().total_vertical_work().total(), 2);
378 BOOST_CHECK_EQUAL(pool.statistics().total_hrz_work().total(), 0);
379 BOOST_CHECK_GE(pool.statistics().total_work_added(), pool.statistics().total_vertical_work().total()+pool.statistics().total_hrz_work().total());
380 BOOST_CHECK_EQUAL(pool.min_time(context), 0U);
381 BOOST_CHECK_EQUAL(pool.min_processors(context), 0U);
382 std::cout<<pool.statistics()<<std::endl;
383 }
384
385 BOOST_AUTO_TEST_CASE_TEMPLATE(logical_and, T, infinite_test_types) {
386 typedef typename T::pool_type pool_type;
387
388 pool_type pool;
389 auto const &context=pool.logical_and(bool_work_type(1), bool_work_type(2));
390 BOOST_CHECK_EQUAL(*context, true);
391 BOOST_CHECK_EQUAL(pool.statistics().total_work_added(), 3);
392
393 BOOST_CHECK_GE(pool.statistics().total_vertical_work().total(), 0);
394 BOOST_CHECK_LE(pool.statistics().total_vertical_work().total(), 3);
395 BOOST_CHECK_EQUAL(pool.statistics().total_hrz_work().total(), 0);
396 BOOST_CHECK_GE(pool.statistics().total_work_added(), pool.statistics().total_vertical_work().total()+pool.statistics().total_hrz_work().total());
397 BOOST_CHECK_EQUAL(pool.min_time(context), 0U);
398 BOOST_CHECK_EQUAL(pool.min_processors(context), 0U);
399 std::cout<<pool.statistics()<<std::endl;
400 }
401
402 BOOST_AUTO_TEST_SUITE_END()
403
404 BOOST_AUTO_TEST_SUITE_END()
405
406 BOOST_AUTO_TEST_SUITE_END()
407
408 BOOST_AUTO_TEST_SUITE_END()