libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
dataflow_priority.cpp
Go to the documentation of this file.
1 /******************************************************************************
2 ** Copyright © 2015 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 <random>
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 priority_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 const 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, unsigned int GSSk>
52 const typename priority_queue_t<Db, Sz, Jn, Mdl, PoolSize, GSSk>::pool_type::pool_type::size_type priority_queue_t<Db, Sz, Jn, Mdl, PoolSize, GSSk>::pool_size;
53 
54 typedef boost::mpl::list<
55 // 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>,
57 // 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>,
58 
59 // 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>
61 
62 typedef boost::mpl::list<
63 // 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>,
64 // 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>
66 
67 // TODO Need to test: pool_traits::size_mode_t::tracks_to_max
68 
69 struct res_t {
70  int i;
71 };
72 
73 struct work_type_simple {
74  int i_;
75 
76  work_type_simple(const int i)
77  : i_(i) {
78  }
79  void __fastcall process(res_t &r) {
80  sleep(1);
81  r.i=i_;
82  }
83 
84  bool __fastcall operator<(work_type_simple const &i) const {
85  return i_<i.i_;
86  }
87 };
88 
89 BOOST_AUTO_TEST_SUITE(thread_pool_tests)
90 
91 BOOST_AUTO_TEST_SUITE(joinable)
92 
93 BOOST_AUTO_TEST_SUITE(finite)
94 
95 BOOST_AUTO_TEST_SUITE(nowait)
96 
97 BOOST_AUTO_TEST_CASE_TEMPLATE(n_threads, T, finite_test_types) {
98  typedef typename T::pool_type pool_type;
99  typedef typename pool_type::joinable joinable;
100  typedef typename pool_type::nonjoinable nonjoinable;
101 
102  constexpr unsigned test_size=1000;
103 
104  std::mt19937_64 gen(42);
105  std::uniform_int_distribution<int> distribution(std::numeric_limits<int>::min()+1, std::numeric_limits<int>::max()-1);
106  auto rand=std::bind(distribution, gen);
107 
108  pool_type pool(T::pool_size);
109  for (unsigned i=0;i<test_size; ++i) {
110  pool<<nonjoinable()<<work_type_simple(rand());
111  }
112  BOOST_CHECK_GT(pool.queue_size(), 0U);
113  auto const &exec=pool<<joinable()<<work_type_simple(std::numeric_limits<int>::min());
114  *exec;
115  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
116  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
117 }
118 
119 BOOST_AUTO_TEST_SUITE_END()
120 
121 BOOST_AUTO_TEST_SUITE(wait_dataflow)
122 
123 BOOST_AUTO_TEST_CASE_TEMPLATE(add_one_work, T, finite_test_types) {
124  typedef typename T::pool_type pool_type;
125  typedef typename pool_type::joinable joinable;
126 
127  constexpr unsigned test_size=10;
128 
129  std::mt19937_64 gen(42);
130  std::uniform_int_distribution<int> distribution(std::numeric_limits<int>::min()+1, std::numeric_limits<int>::max()-1);
131  auto rand=std::bind(distribution, gen);
132 
133  pool_type pool(T::pool_size);
134  for (unsigned i=0;i<test_size; ++i) {
135  auto const &exec0=pool<<joinable()<<work_type_simple(rand());
136  auto const &exec1=pool<<joinable()<<work_type_simple(rand());
137  auto const &exec2=pool<<joinable()<<work_type_simple(rand());
138  auto const &exec3=pool<<joinable()<<work_type_simple(rand());
139  auto const &exec4=pool<<joinable()<<work_type_simple(rand());
140  auto const &exec5=pool<<joinable()<<work_type_simple(rand());
141  auto const &exec6=pool<<joinable()<<work_type_simple(rand());
142  auto const &exec7=pool<<joinable()<<work_type_simple(rand());
143  auto const &exec8=pool<<joinable()<<work_type_simple(rand());
144  auto const &exec9=pool<<joinable()<<work_type_simple(rand());
145  *exec0;
146  *exec1;
147  *exec2;
148  *exec3;
149  *exec4;
150  *exec5;
151  *exec6;
152  *exec7;
153  *exec8;
154  *exec9;
155  }
156  BOOST_CHECK_EQUAL(pool.pool_size(), T::pool_size);
157  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
158 }
159 
160 BOOST_AUTO_TEST_SUITE_END()
161 
162 BOOST_AUTO_TEST_SUITE_END()
163 
164 BOOST_AUTO_TEST_SUITE(infinite)
165 
166 BOOST_AUTO_TEST_SUITE(wait_dataflow)
167 
168 BOOST_AUTO_TEST_CASE_TEMPLATE(add_one_work, T, infinite_test_types) {
169  typedef typename T::pool_type pool_type;
170  typedef typename pool_type::joinable joinable;
171 
172  constexpr unsigned test_size=100;
173 
174  std::mt19937_64 gen(42);
175  std::uniform_int_distribution<int> distribution(std::numeric_limits<int>::min()+1, std::numeric_limits<int>::max()-1);
176  auto rand=std::bind(distribution, gen);
177 
178  pool_type pool;
179  for (unsigned i=0;i<test_size; ++i) {
180  auto const &exec0=pool<<joinable()<<work_type_simple(rand());
181  auto const &exec1=pool<<joinable()<<work_type_simple(rand());
182  auto const &exec2=pool<<joinable()<<work_type_simple(rand());
183  auto const &exec3=pool<<joinable()<<work_type_simple(rand());
184  auto const &exec4=pool<<joinable()<<work_type_simple(rand());
185  auto const &exec5=pool<<joinable()<<work_type_simple(rand());
186  auto const &exec6=pool<<joinable()<<work_type_simple(rand());
187  auto const &exec7=pool<<joinable()<<work_type_simple(rand());
188  auto const &exec8=pool<<joinable()<<work_type_simple(rand());
189  auto const &exec9=pool<<joinable()<<work_type_simple(rand());
190  *exec0;
191  *exec1;
192  *exec2;
193  *exec3;
194  *exec4;
195  *exec5;
196  *exec6;
197  *exec7;
198  *exec8;
199  *exec9;
200  }
201  BOOST_CHECK_EQUAL(pool.queue_size(), 0U);
202 }
203 
204 BOOST_AUTO_TEST_SUITE_END()
205 
206 BOOST_AUTO_TEST_SUITE_END()
207 
208 BOOST_AUTO_TEST_SUITE_END()
209 
210 BOOST_AUTO_TEST_SUITE_END()