libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
dataflow_full.cpp
Go to the documentation of this file.
1 /******************************************************************************
2 ** Copyright © 2002 by J.M.McGuiness, coder@hussar.me.uk
3 **
4 ** This library is free software; you can redistribute it and/or
5 ** modify it under the terms of the GNU Lesser General Public
6 ** License as published by the Free Software Foundation; either
7 ** version 2.1 of the License, or (at your option) any later version.
8 **
9 ** This library is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ** Lesser General Public License for more details.
13 **
14 ** You should have received a copy of the GNU Lesser General Public
15 ** License along with this library; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 
19 #include "stdafx.h"
20 
21 #define BOOST_TEST_MODULE libjmmcg_tests
22 #include <boost/test/included/unit_test.hpp>
23 
24 #include <boost/mpl/list.hpp>
25 
26 #include "core/thread_pool_sequential.hpp"
27 #include "core/thread_pool_master.hpp"
28 #include "core/thread_pool_workers.hpp"
29 
30 #include <boost/bind/bind.hpp>
31 
32 using namespace libjmmcg;
33 using namespace ppd;
34 
35 template<class Db, pool_traits::size_mode_t Sz, generic_traits::return_data Jn, class Mdl, unsigned int PoolSize=0, unsigned int GSSk=1>
36 struct fifo_queue_t {
37  typedef pool_aspects<
38  Jn,
40  Mdl,
42  std::less,
43  GSSk
45 
46  typedef thread_pool<Db, Sz, thread_pool_traits> pool_type;
47 
48  static inline constexpr typename pool_type::pool_type::size_type pool_size=PoolSize;
49 };
50 
51 template<class Db, pool_traits::size_mode_t Sz, generic_traits::return_data Jn, class Mdl, unsigned int PoolSize=0, unsigned int GSSk=1>
52 struct lifo_queue_t {
53  typedef pool_aspects<
54  Jn,
56  Mdl,
58  std::less,
59  GSSk
61 
62  typedef thread_pool<Db, Sz, thread_pool_traits> pool_type;
63 
64  static inline constexpr typename pool_type::pool_type::size_type pool_size=PoolSize;
65 };
66 
67 template<class Db, pool_traits::size_mode_t Sz, generic_traits::return_data Jn, class Mdl, unsigned int PoolSize=0, unsigned int GSSk=1>
68 struct priority_queue_t {
69  typedef pool_aspects<
70  Jn,
72  Mdl,
74  std::less,
75  GSSk
77 
78  typedef thread_pool<Db, Sz, thread_pool_traits> pool_type;
79 
80  static inline constexpr typename pool_type::pool_type::size_type pool_size=PoolSize;
81 };
82 
83 typedef boost::mpl::list<
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::sequential, generic_traits::return_data::joinable, sequential_mode>,
85  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>,
86  priority_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>,
87 
88  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, 1>,
89 // TODO 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, 1, 2>,
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, 1>,
91 // TODO 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, 1, 2>,
92  priority_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, 1>,
93 // TODO priority_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, 1, 2>,
94 
95  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, 2>,
96  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, 2>,
97  priority_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, 2>
98 > finite_test_types;
99 
100 typedef boost::mpl::list<
101  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>,
102  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>,
103  priority_queue_t<pool_traits::work_distribution_mode_t::one_thread_distributes<>, pool_traits::size_mode_t::sequential, generic_traits::return_data::joinable, sequential_mode>,
104 /* TODO not yet finished coding these types!
105  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>,
106  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>,
107  priority_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>,
108 
109  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::infinite, generic_traits::return_data::joinable, heavyweight_threading>,
110  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::infinite, generic_traits::return_data::joinable, heavyweight_threading>,
111  priority_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::infinite, generic_traits::return_data::joinable, heavyweight_threading>,
112 */
113  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>,
114  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>,
115  priority_queue_t<pool_traits::work_distribution_mode_t::one_thread_distributes<>, pool_traits::size_mode_t::infinite, generic_traits::return_data::joinable, heavyweight_threading>
116 > infinite_test_types;
117 
118 // TODO Need to test: pool_traits::size_mode_t::tracks_to_max
119 
120 struct res_t {
121  long i;
122 };
123 
124 struct work_type {
126 
127  int i_;
128 
129  explicit work_type(const int i)
130  : i_(i) {
131  }
132  void __fastcall process(result_type &r) noexcept(true) {
133  r.i=i_<<1;
134  }
135  void __fastcall mutate(result_type &r) noexcept(true) {
136  process(r);
137  }
138 
139  bool __fastcall operator<(work_type const &i) const {
140  return i_<i.i_;
141  }
142 };
143 
144 struct work_type_simple {
145  int i_;
146 
147  work_type_simple(const int i)
148  : i_(i) {
149  }
150  void __fastcall process(res_t &r) {
151  r.i=(i_<<1);
152  }
153  void __fastcall mutate(res_t &r) {
154  process(r);
155  }
157  res_t r;
158  process(r);
159  return r;
160  }
161 
162  bool __fastcall operator<(work_type_simple const &i) const {
163  return i_<i.i_;
164  }
165 };
166 
167 struct bad_return_type {};
168 
169 template<generic_traits::api_type API, typename Mdl>
171  typedef void result_type;
172 
173  static inline bool waiting{false};
174 
175  void __fastcall process() noexcept(true) {
176  while (waiting) {
177  api_threading_traits<API, Mdl>::sleep(10);
178  }
179  }
180  bool __fastcall operator<(erase_test_work_type const &) const {
181  return true;
182  }
183 };
184 template<generic_traits::api_type API>
185 struct erase_test_work_type<API, sequential_mode> {
186  typedef void result_type;
187 
188  static inline bool waiting{true};
189 
190  void __fastcall process() noexcept(true) {
191  }
192  bool __fastcall operator<(erase_test_work_type const &) const {
193  return true;
194  }
195 };
196 
198  typedef bool result_type;
199 
200  int i_;
201 
202  explicit bool_work_type(const int i)
203  : i_(i) {
204  }
205  void __fastcall process(result_type &r) const {
206  r=static_cast<bool>(i_);
207  }
208  bool __fastcall operator<(bool_work_type const &) const {
209  return true;
210  }
211 };
212 
215  typedef std::runtime_error exception_t;
216 
217  void __fastcall process(result_type &) noexcept(false) {
218  throw exception_t("test");
219  }
220  void __fastcall mutate(result_type &r) noexcept(false) {
221  process(r);
222  }
223 
224  bool __fastcall operator<(throw_work_type const &) const {
225  return true;
226  }
227 };
228 
229 template<generic_traits::api_type API, typename Mdl>
231  typedef void result_type;
232 
233  bool &release;
234 
235  explicit horizontal_work_type(bool &r) noexcept(true)
236  : release(r) {
237  }
238 
239  void __fastcall process() noexcept(false) {
240  while (!release) {
241  api_threading_traits<API, Mdl>::sleep(10);
242  }
243  }
244  bool __fastcall operator<(horizontal_work_type const &) const {
245  return true;
246  }
247 };
248 template<generic_traits::api_type API>
249 struct horizontal_work_type<API, sequential_mode> {
250  typedef void result_type;
251 
252  bool &release;
253 
254  explicit horizontal_work_type(bool &r) noexcept(true)
255  : release(r) {
256  }
257 
258  void __fastcall process() noexcept(true) {
259  }
260  bool __fastcall operator<(horizontal_work_type const &) const {
261  return true;
262  }
263 };
264 
265 template<generic_traits::api_type API, typename Mdl>
267  typedef void result_type;
268 
269  bool &release;
270 
271  explicit horizontal_work_type_rel(bool &r) noexcept(true)
272  : release(r) {}
273 
274  void __fastcall process() noexcept(true) {
275  release=true;
276  }
277  bool __fastcall operator<(horizontal_work_type_rel const &) const {
278  return true;
279  }
280 };
281 
282 BOOST_AUTO_TEST_SUITE(thread_pool_tests)
283 
284 BOOST_AUTO_TEST_SUITE(joinable)
285 
286 BOOST_AUTO_TEST_SUITE(finite)
287 
288 BOOST_AUTO_TEST_SUITE(nowait)
289 
290 BOOST_AUTO_TEST_CASE_TEMPLATE(one_thread, T, finite_test_types) {
291  typedef typename T::pool_type pool_type;
292 
293  pool_type pool(1);
294  BOOST_CHECK_EQUAL(pool.pool_size(), 1U);
295  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
296  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::erew_memory_access), 0U);
297  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::erew_memory_access), 0U);
298  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::crew_memory_access), 0U);
299  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::crew_memory_access), 0U);
300 }
301 
302 BOOST_AUTO_TEST_CASE_TEMPLATE(n_threads, T, finite_test_types) {
303  typedef typename T::pool_type pool_type;
304 
305  pool_type pool(T::pool_size);
306  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
307  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
308  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::erew_memory_access), 0U);
309  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::erew_memory_access), 0U);
310  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::crew_memory_access), 0U);
311  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::crew_memory_access), 0U);
312 }
313 
314 BOOST_AUTO_TEST_SUITE_END()
315 
316 BOOST_AUTO_TEST_SUITE(wait_dataflow)
317 
318 BOOST_AUTO_TEST_CASE_TEMPLATE(add_one_work, T, finite_test_types) {
319  typedef typename T::pool_type pool_type;
320  typedef typename pool_type::joinable joinable;
321 
322  pool_type pool(T::pool_size);
323  auto const &exec=pool<<joinable()<<work_type_simple(1);
324  BOOST_CHECK_EQUAL(exec->i, 2);
325  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
326  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
327  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::erew_memory_access), 0U);
328  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::erew_memory_access), 0U);
329  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::crew_memory_access), 0U);
330  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::crew_memory_access), 0U);
331  BOOST_CHECK_EQUAL(pool.min_time(exec), 0U);
332  BOOST_CHECK_EQUAL(pool.min_processors(exec), 0U);
333 }
334 
335 BOOST_AUTO_TEST_CASE_TEMPLATE(add_one_work_boost_bind, T, finite_test_types) {
336  typedef typename T::pool_type pool_type;
337  typedef typename pool_type::joinable joinable;
338 
339  pool_type pool(T::pool_size);
340  auto const &exec=pool<<joinable()<<boost::bind(&work_type_simple::exec, work_type_simple(1));
341  BOOST_CHECK_EQUAL(exec->i, 2);
342  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
343  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
344  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::erew_memory_access), 0U);
345  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::erew_memory_access), 0U);
346  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::crew_memory_access), 0U);
347  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::crew_memory_access), 0U);
348  BOOST_CHECK_EQUAL(pool.min_time(exec), 0U);
349  BOOST_CHECK_EQUAL(pool.min_processors(exec), 0U);
350 }
351 
352 BOOST_AUTO_TEST_CASE_TEMPLATE(erase_one_work_after_waiting, T, finite_test_types) {
353  typedef typename T::pool_type pool_type;
354  typedef typename pool_type::joinable joinable;
355 
356  pool_type pool(T::pool_size);
357  auto &&exec=pool<<joinable()<<work_type(1);
358  *exec;
359  pool.erase(exec);
360  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
361  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
362  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::erew_memory_access), 0U);
363  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::erew_memory_access), 0U);
364  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::crew_memory_access), 0U);
365  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::crew_memory_access), 0U);
366  BOOST_CHECK_EQUAL(pool.min_time(exec), 0U);
367  BOOST_CHECK_EQUAL(pool.min_processors(exec), 0U);
368 }
369 
370 BOOST_AUTO_TEST_CASE_TEMPLATE(access_erased_work, T, finite_test_types) {
371  typedef typename T::pool_type pool_type;
372  typedef typename pool_type::nonjoinable nonjoinable;
373  typedef typename pool_type::joinable joinable;
374 
375  typedef erase_test_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> erase_wk_t;
376 
377  pool_type pool(T::pool_size);
378  // Block the pool.
379  for (typename pool_type::pool_type::size_type i=0; i<pool.pool_size(); ++i) {
380  pool<<nonjoinable()<<erase_wk_t();
381  }
382  // Now this work is added, it will wait in the queue.
383  auto &&exec=pool<<joinable()<<work_type_simple(1);
384  pool.erase(exec);
385  bool exeception_caught=std::is_same<typename T::thread_pool_traits::os_traits::thread_traits::model_type, sequential_mode>::value;
386  try {
387  [[maybe_unused]] auto const ret=exec->i;
388  } catch (const typename pool_type::exception_type &) {
389  exeception_caught=true;
390  }
391  // Release the threads in the pool.
392  erase_wk_t::waiting=false;
393  api_threading_traits<T::thread_pool_traits::os_traits::thread_traits::api_params_type::api_type, typename T::thread_pool_traits::os_traits::thread_traits::model_type>::sleep(100);
394  BOOST_CHECK_EQUAL(exeception_caught, true);
395  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
396  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
397  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::erew_memory_access), 0U);
398  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::erew_memory_access), 0U);
399  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::crew_memory_access), 0U);
400  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::crew_memory_access), 0U);
401  BOOST_CHECK_EQUAL(pool.min_time(exec), 0U);
402  BOOST_CHECK_EQUAL(pool.min_processors(exec), 0U);
403 }
404 
405 BOOST_AUTO_TEST_CASE_TEMPLATE(add_one_work_time_critical, T, finite_test_types) {
406  typedef typename T::pool_type pool_type;
407  typedef typename pool_type::joinable joinable;
408  typedef typename pool_type::template priority<pool_type::api_params_type::time_critical> time_critical;
409 
410  pool_type pool(T::pool_size);
411  auto const &exec=pool<<joinable()<<time_critical()<<work_type_simple(1);
412  BOOST_CHECK_EQUAL(exec->i, 2);
413  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
414  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
415  BOOST_CHECK_EQUAL(pool.min_time(exec), 0U);
416  BOOST_CHECK_EQUAL(pool.min_processors(exec), 0U);
417 }
418 
419 BOOST_AUTO_TEST_CASE_TEMPLATE(add_one_work_throw_exception, T, finite_test_types) {
420  typedef typename T::pool_type pool_type;
421  typedef typename pool_type::joinable joinable;
422 
423  bool exception_caught=false;
424  pool_type pool(T::pool_size);
425  try {
426  auto const &exec=pool<<joinable()<<throw_work_type();
427  *exec;
428  } catch (throw_work_type::exception_t const &e) {
429  exception_caught=(std::string(e.what())=="test");
430  } catch (...) {
431  exception_caught=false;
432  }
433  BOOST_CHECK_EQUAL(exception_caught, true);
434 }
435 
436 BOOST_AUTO_TEST_CASE_TEMPLATE(add_two_work, T, finite_test_types) {
437  typedef typename T::pool_type pool_type;
438  typedef typename pool_type::joinable joinable;
439 
440  pool_type pool(T::pool_size);
441  auto const &exec=pool<<joinable()<<work_type_simple(1);
442  auto const &exec2=pool<<joinable()<<work_type_simple(3);
443  BOOST_CHECK_EQUAL(exec->i, 2);
444  BOOST_CHECK_EQUAL(exec2->i, 6);
445  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
446  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
447  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::erew_memory_access), 0U);
448  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::erew_memory_access), 0U);
449  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::crew_memory_access), 0U);
450  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::crew_memory_access), 0U);
451 }
452 
453 BOOST_AUTO_TEST_CASE_TEMPLATE(horizontal_threading, T, finite_test_types) {
454  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;
455  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;
456  typedef typename T::pool_type pool_type;
457  typedef typename pool_type::joinable joinable;
458 
459  pool_type pool(T::pool_size);
460  bool release=false;
461  hrz_wk_t hz(release);
462  hrz_wk_rel_t hz_rel(release);
463  auto const &exec=pool<<joinable()<<hz;
464  auto const &exec_rel=pool<<joinable()<<hz_rel;
465  *exec;
466  *exec_rel;
467  BOOST_CHECK_EQUAL(hz.release, true);
468  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
469 }
470 
471 BOOST_AUTO_TEST_CASE_TEMPLATE(unary_fn, T, finite_test_types) {
472  typedef typename T::pool_type pool_type;
473 
474  pool_type pool(T::pool_size);
475  auto const &exec=pool.unary_fun(bool_work_type(0), std::logical_not<bool_work_type::result_type>());
476  BOOST_CHECK_EQUAL(*exec, true);
477  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
478  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
479  BOOST_CHECK_EQUAL(pool.min_time(exec), 0U);
480  BOOST_CHECK_EQUAL(pool.min_processors(exec), 0U);
481 }
482 
483 BOOST_AUTO_TEST_CASE_TEMPLATE(logical_and_false, T, finite_test_types) {
484  typedef typename T::pool_type pool_type;
485 
486  pool_type pool(T::pool_size);
487  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
488  auto const &exec=pool.logical_and(bool_work_type(0), bool_work_type(2));
489  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
490  BOOST_CHECK_EQUAL(*exec, false);
491  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
492  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
493  BOOST_CHECK_EQUAL(pool.min_time(exec), 0U);
494  BOOST_CHECK_EQUAL(pool.min_processors(exec), 0U);
495 }
496 
497 BOOST_AUTO_TEST_CASE_TEMPLATE(logical_and_true, T, finite_test_types) {
498  typedef typename T::pool_type pool_type;
499 
500  pool_type pool(T::pool_size);
501  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
502  auto const &exec=pool.logical_and(bool_work_type(1), bool_work_type(2));
503  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
504  BOOST_CHECK_EQUAL(*exec, true);
505  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
506  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
507  BOOST_CHECK_EQUAL(pool.min_time(exec), 0U);
508  BOOST_CHECK_EQUAL(pool.min_processors(exec), 0U);
509 }
510 
511 BOOST_AUTO_TEST_CASE_TEMPLATE(logical_or_false, T, finite_test_types) {
512  typedef typename T::pool_type pool_type;
513 
514  pool_type pool(T::pool_size);
515  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
516  auto const &exec=pool.logical_or(bool_work_type(0), bool_work_type(0));
517  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
518  BOOST_CHECK_EQUAL(*exec, false);
519  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
520  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
521  BOOST_CHECK_EQUAL(pool.min_time(exec), 0U);
522  BOOST_CHECK_EQUAL(pool.min_processors(exec), 0U);
523 }
524 
525 BOOST_AUTO_TEST_CASE_TEMPLATE(logical_or_true, T, finite_test_types) {
526  typedef typename T::pool_type pool_type;
527 
528  pool_type pool(T::pool_size);
529  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
530  auto const &exec=pool.logical_or(bool_work_type(1), bool_work_type(2));
531  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
532  BOOST_CHECK_EQUAL(*exec, true);
533  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
534  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
535  BOOST_CHECK_EQUAL(pool.min_time(exec), 0U);
536  BOOST_CHECK_EQUAL(pool.min_processors(exec), 0U);
537 }
538 
539 BOOST_AUTO_TEST_SUITE_END()
540 
541 BOOST_AUTO_TEST_SUITE_END()
542 
543 BOOST_AUTO_TEST_SUITE(infinite)
544 
545 BOOST_AUTO_TEST_SUITE(nowait)
546 
547 BOOST_AUTO_TEST_CASE_TEMPLATE(default_ctor, T, infinite_test_types) {
548  typedef typename T::pool_type pool_type;
549 
550  pool_type pool;
551  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
552  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::erew_memory_access), 0U);
553  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::erew_memory_access), 0U);
554  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::crew_memory_access), 0U);
555  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::crew_memory_access), 0U);
556 }
557 
558 BOOST_AUTO_TEST_SUITE_END()
559 
560 BOOST_AUTO_TEST_SUITE(wait_dataflow)
561 
562 BOOST_AUTO_TEST_CASE_TEMPLATE(add_one_work, T, infinite_test_types) {
563  typedef typename T::pool_type pool_type;
564  typedef typename pool_type::joinable joinable;
565 
566  pool_type pool;
567  auto const &exec=pool<<joinable()<<work_type_simple(1);
568  BOOST_CHECK_EQUAL(exec->i, 2);
569  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
570  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::erew_memory_access), 0U);
571  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::erew_memory_access), 0U);
572  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::crew_memory_access), 0U);
573  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::crew_memory_access), 0U);
574  BOOST_CHECK_EQUAL(pool.min_time(exec), 0U);
575  BOOST_CHECK_EQUAL(pool.min_processors(exec), 0U);
576 }
577 
578 BOOST_AUTO_TEST_CASE_TEMPLATE(add_one_work_boost_bind, T, infinite_test_types) {
579  typedef typename T::pool_type pool_type;
580  typedef typename pool_type::joinable joinable;
581 
582  pool_type pool;
583  auto const &exec=pool<<joinable()<<boost::bind(&work_type_simple::exec, work_type_simple(1));
584  BOOST_CHECK_EQUAL(exec->i, 2);
585  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
586  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::erew_memory_access), 0U);
587  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::erew_memory_access), 0U);
588  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::crew_memory_access), 0U);
589  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::crew_memory_access), 0U);
590  BOOST_CHECK_EQUAL(pool.min_time(exec), 0U);
591  BOOST_CHECK_EQUAL(pool.min_processors(exec), 0U);
592 }
593 
594 BOOST_AUTO_TEST_CASE_TEMPLATE(add_one_work_time_critical, T, infinite_test_types) {
595  typedef typename T::pool_type pool_type;
596  typedef typename pool_type::joinable joinable;
597  typedef typename pool_type::template priority<pool_type::api_params_type::time_critical> time_critical;
598 
599  pool_type pool;
600  auto const &exec=pool<<joinable()<<time_critical()<<work_type_simple(1);
601  BOOST_CHECK_EQUAL(exec->i, 2);
602  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
603  BOOST_CHECK_EQUAL(pool.min_time(exec), 0U);
604  BOOST_CHECK_EQUAL(pool.min_processors(exec), 0U);
605 }
606 
607 BOOST_AUTO_TEST_CASE_TEMPLATE(add_one_work_throw_exception, T, infinite_test_types) {
608  typedef typename T::pool_type pool_type;
609  typedef typename pool_type::joinable joinable;
610 
611  bool exception_caught=false;
612  pool_type pool;
613  try {
614  auto const &exec=pool<<joinable()<<throw_work_type();
615  *exec;
616  } catch (throw_work_type::exception_t const &e) {
617  exception_caught=(std::string(e.what())=="test");
618  } catch (...) {
619  exception_caught=false;
620  }
621  BOOST_CHECK_EQUAL(exception_caught, true);
622 }
623 
624 BOOST_AUTO_TEST_CASE_TEMPLATE(add_two_work, T, infinite_test_types) {
625  typedef typename T::pool_type pool_type;
626  typedef typename pool_type::joinable joinable;
627 
628  pool_type pool;
629  auto const &exec=pool<<joinable()<<work_type_simple(1);
630  auto const &exec2=pool<<joinable()<<work_type_simple(3);
631  BOOST_CHECK_EQUAL(exec->i, 2);
632  BOOST_CHECK_EQUAL(exec2->i, 6);
633  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
634  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::erew_memory_access), 0U);
635  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::erew_memory_access), 0U);
636  BOOST_CHECK_EQUAL(pool.min_time(generic_traits::memory_access_modes::crew_memory_access), 0U);
637  BOOST_CHECK_EQUAL(pool.min_processors(generic_traits::memory_access_modes::crew_memory_access), 0U);
638 }
639 
640 BOOST_AUTO_TEST_CASE_TEMPLATE(unary_fn, T, infinite_test_types) {
641  typedef typename T::pool_type pool_type;
642 
643  pool_type pool;
644  auto const &exec=pool.unary_fun(bool_work_type(1),std::logical_not<bool_work_type::result_type>());
645  BOOST_CHECK_EQUAL(*exec, false);
646  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
647  BOOST_CHECK_EQUAL(pool.min_time(exec), 0U);
648  BOOST_CHECK_EQUAL(pool.min_processors(exec), 0U);
649 }
650 
651 BOOST_AUTO_TEST_CASE_TEMPLATE(logical_and_false, T, infinite_test_types) {
652  typedef typename T::pool_type pool_type;
653 
654  pool_type pool;
655  auto const &exec=pool.logical_and(bool_work_type(0), bool_work_type(2));
656  BOOST_CHECK_EQUAL(*exec, false);
657  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
658  BOOST_CHECK_EQUAL(pool.min_time(exec), 0U);
659  BOOST_CHECK_EQUAL(pool.min_processors(exec), 0U);
660 }
661 
662 BOOST_AUTO_TEST_CASE_TEMPLATE(logical_and_true, T, infinite_test_types) {
663  typedef typename T::pool_type pool_type;
664 
665  pool_type pool;
666  auto const &exec=pool.logical_and(bool_work_type(1), bool_work_type(2));
667  BOOST_CHECK_EQUAL(*exec, true);
668  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
669  BOOST_CHECK_EQUAL(pool.min_time(exec), 0U);
670  BOOST_CHECK_EQUAL(pool.min_processors(exec), 0U);
671 }
672 
673 BOOST_AUTO_TEST_CASE_TEMPLATE(logical_or_false, T, infinite_test_types) {
674  typedef typename T::pool_type pool_type;
675 
676  pool_type pool;
677  auto const &exec=pool.logical_or(bool_work_type(0), bool_work_type(0));
678  BOOST_CHECK_EQUAL(*exec, false);
679  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
680  BOOST_CHECK_EQUAL(pool.min_time(exec), 0U);
681  BOOST_CHECK_EQUAL(pool.min_processors(exec), 0U);
682 }
683 
684 BOOST_AUTO_TEST_CASE_TEMPLATE(logical_or_true, T, infinite_test_types) {
685  typedef typename T::pool_type pool_type;
686 
687  pool_type pool;
688  auto const &exec=pool.logical_or(bool_work_type(1), bool_work_type(2));
689  BOOST_CHECK_EQUAL(*exec, true);
690  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
691  BOOST_CHECK_EQUAL(pool.min_time(exec), 0U);
692  BOOST_CHECK_EQUAL(pool.min_processors(exec), 0U);
693 }
694 
695 BOOST_AUTO_TEST_SUITE_END()
696 
697 BOOST_AUTO_TEST_SUITE_END()
698 
699 BOOST_AUTO_TEST_SUITE_END()
700 
701 BOOST_AUTO_TEST_SUITE_END()