21 #define BOOST_TEST_MODULE libjmmcg_tests
22 #include <boost/test/included/unit_test.hpp>
24 #include "core/intrusive.hpp"
26 #include "core/ave_deviation_meter.hpp"
27 #include "core/stats_output.hpp"
28 #include "core/thread_wrapper.hpp"
33 using namespace libjmmcg;
36 using lock_t=api_lock_traits<platform_api, heavyweight_threading>;
39 struct data
final :
public intrusive::node_details_itf<lock_t>,
public sp_counter_type<
typename intrusive::node_details_itf<lock_t>::atomic_ctr_t::value_type, lock_t> {
47 explicit data(
int j)
noexcept(
true)
59 template<
unsigned short N,
class Cont,
template<
class>
class Ins>
60 struct add_thread
final :
public wrapper<platform_api, heavyweight_threading> {
71 colln.reserve(num_elems);
74 std::back_inserter(colln),
76 [&elem,
this]() ->
typename container_type::value_type {
78 return typename container_type::value_type(
new typename container_type::value_type::value_type(N*num_elems+(++elem)));
83 base_t::wait_thread_exit();
87 std::copy_n(colln.begin(), num_elems, inserting);
93 struct pop_thread
final :
public wrapper<platform_api, heavyweight_threading> {
105 base_t::wait_thread_exit();
110 assert(!cont.empty());
117 BOOST_AUTO_TEST_SUITE(instrusive_parallel_tests)
119 BOOST_AUTO_TEST_SUITE(stack)
123 BOOST_AUTO_TEST_SUITE(performance, *stats_to_csv::make_fixture(
"intrusive_parallel.csv"))
130 BOOST_AUTO_TEST_CASE(push)
132 #ifdef JMMCG_PERFORMANCE_TESTS
133 const container_type::size_type num_tests=100;
135 const container_type::size_type num_tests=1;
138 const std::pair<timed_results_t,
bool> timed_results(compute_average_deviation<timed_results_t::value_type>(
142 #ifdef JMMCG_PERFORMANCE_TESTS
143 const container_type::size_type num_items=10000;
145 const container_type::size_type num_items=1000;
148 std::chrono::high_resolution_clock::time_point t1, t2;
151 add_thread<1, container_type, std::front_insert_iterator> thread1(num_items, std::front_inserter(s));
152 add_thread<2, container_type, std::front_insert_iterator> thread2(num_items, std::front_inserter(s));
153 add_thread<3, container_type, std::front_insert_iterator> thread3(num_items, std::front_inserter(s));
154 add_thread<4, container_type, std::front_insert_iterator> thread4(num_items, std::front_inserter(s));
156 t1=std::chrono::high_resolution_clock::now();
157 thread1.create_running();
158 thread2.create_running();
159 thread3.create_running();
160 thread4.create_running();
162 api_threading_traits<platform_api, heavyweight_threading>::sleep(100);
163 }
while (thread1.is_running() || thread2.is_running() || thread3.is_running() || thread4.is_running());
165 t2=std::chrono::high_resolution_clock::now();
169 BOOST_CHECK(!s.empty());
170 BOOST_CHECK_EQUAL(s.size(), 4*num_items);
171 BOOST_CHECK_EQUAL(s.size_n(), 4*num_items);
173 for (
auto const &iter : s) {
174 BOOST_CHECK_GE(iter->sp_count(), 1);
175 BOOST_CHECK_EQUAL(iter->sp_count(), 3);
178 std::set<
int> check_list_integrity;
182 std::inserter(check_list_integrity, check_list_integrity.begin()),
183 [](container_type::value_type
const &v) {
187 BOOST_CHECK_EQUAL(check_list_integrity.size(), 4*num_items);
189 return timed_results_t::value_type(4*1000000/
static_cast<
double>(std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count()))/num_items;
192 #ifdef JMMCG_PERFORMANCE_TESTS
193 stats_to_csv::handle->stats<<timed_results.first.to_csv()<<std::flush;
194 BOOST_CHECK(!timed_results.second);
203 BOOST_AUTO_TEST_CASE(pop)
205 #ifdef JMMCG_PERFORMANCE_TESTS
206 const container_type::size_type num_tests=100;
208 const container_type::size_type num_tests=1;
211 const std::pair<timed_results_t,
bool> timed_results(compute_average_deviation<timed_results_t::value_type>(
215 #ifdef JMMCG_PERFORMANCE_TESTS
216 const container_type::size_type num_items=10000;
218 const container_type::size_type num_items=1000;
221 container_type::size_type elem=0;
222 std::chrono::high_resolution_clock::time_point t1, t2;
224 std::front_inserter(s),
228 return container_type::value_type(
new container_type::value_type::value_type(++elem));
233 pop_thread<container_type> thread1(num_items, s);
234 pop_thread<container_type> thread2(num_items, s);
235 pop_thread<container_type> thread3(num_items, s);
236 pop_thread<container_type> thread4(num_items, s);
238 t1=std::chrono::high_resolution_clock::now();
239 thread1.create_running();
240 thread2.create_running();
241 thread3.create_running();
242 thread4.create_running();
244 api_threading_traits<platform_api, heavyweight_threading>::sleep(100);
245 }
while (thread1.is_running() || thread2.is_running() || thread3.is_running() || thread4.is_running());
247 t2=std::chrono::high_resolution_clock::now();
251 BOOST_CHECK(s.empty());
252 BOOST_CHECK_EQUAL(s.size(), container_type::size_type());
253 BOOST_CHECK_EQUAL(s.size_n(), container_type::size_type());
254 return timed_results_t::value_type(4*1000000/
static_cast<
double>(std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count()))/num_items;
257 #ifdef JMMCG_PERFORMANCE_TESTS
258 stats_to_csv::handle->stats<<timed_results.first.to_csv()<<std::flush;
259 BOOST_CHECK(!timed_results.second);
263 BOOST_AUTO_TEST_SUITE_END()
265 BOOST_AUTO_TEST_SUITE(slist)
274 BOOST_AUTO_TEST_CASE(push_front)
276 #ifdef JMMCG_PERFORMANCE_TESTS
277 const container_type::size_type num_tests=100;
279 const container_type::size_type num_tests=1;
282 const std::pair<timed_results_t,
bool> timed_results(compute_average_deviation<timed_results_t::value_type>(
286 #ifdef JMMCG_PERFORMANCE_TESTS
287 const container_type::size_type num_items=10000;
289 const container_type::size_type num_items=1000;
292 std::chrono::high_resolution_clock::time_point t1, t2;
295 add_thread<1, container_type, std::front_insert_iterator> thread1(num_items, std::front_inserter(s));
296 add_thread<2, container_type, std::front_insert_iterator> thread2(num_items, std::front_inserter(s));
297 add_thread<3, container_type, std::front_insert_iterator> thread3(num_items, std::front_inserter(s));
298 add_thread<4, container_type, std::front_insert_iterator> thread4(num_items, std::front_inserter(s));
300 t1=std::chrono::high_resolution_clock::now();
301 thread1.create_running();
302 thread2.create_running();
303 thread3.create_running();
304 thread4.create_running();
306 api_threading_traits<platform_api, heavyweight_threading>::sleep(100);
307 }
while (thread1.is_running() || thread2.is_running() || thread3.is_running() || thread4.is_running());
309 t2=std::chrono::high_resolution_clock::now();
313 BOOST_CHECK(!s.empty());
314 BOOST_CHECK_EQUAL(s.size(), 4*num_items);
315 BOOST_CHECK_EQUAL(s.size_n(), 4*num_items);
317 for (
auto const &iter : s) {
318 BOOST_CHECK_GE(iter->sp_count(), 1);
319 BOOST_CHECK_EQUAL(iter->sp_count(), 3);
322 std::set<
int> check_list_integrity;
326 std::inserter(check_list_integrity, check_list_integrity.begin()),
327 [](container_type::value_type
const &v) {
331 BOOST_CHECK_EQUAL(check_list_integrity.size(), 4*num_items);
333 BOOST_CHECK(s.penultimate_reachable_from_prefront());
334 return timed_results_t::value_type(4*1000000/
static_cast<
double>(std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count()))/num_items;
337 #ifdef JMMCG_PERFORMANCE_TESTS
338 stats_to_csv::handle->stats<<timed_results.first.to_csv()<<std::flush;
339 BOOST_CHECK(!timed_results.second);
393 BOOST_AUTO_TEST_CASE(pop_front)
395 #ifdef JMMCG_PERFORMANCE_TESTS
396 const container_type::size_type num_tests=100;
398 const container_type::size_type num_tests=1;
401 const std::pair<timed_results_t,
bool> timed_results(compute_average_deviation<timed_results_t::value_type>(
405 #ifdef JMMCG_PERFORMANCE_TESTS
406 const container_type::size_type num_items=10000;
408 const container_type::size_type num_items=1000;
411 container_type::size_type elem=0;
412 std::chrono::high_resolution_clock::time_point t1, t2;
414 std::front_inserter(s),
416 [&elem]() -> container_type::value_type {
418 return container_type::value_type(
new container_type::value_type::value_type(++elem));
423 pop_thread<container_type> thread1(num_items, s);
424 pop_thread<container_type> thread2(num_items, s);
425 pop_thread<container_type> thread3(num_items, s);
426 pop_thread<container_type> thread4(num_items, s);
428 t1=std::chrono::high_resolution_clock::now();
429 thread1.create_running();
430 thread2.create_running();
431 thread3.create_running();
432 thread4.create_running();
434 api_threading_traits<platform_api, heavyweight_threading>::sleep(100);
435 }
while (thread1.is_running() || thread2.is_running() || thread3.is_running() || thread4.is_running());
437 t2=std::chrono::high_resolution_clock::now();
441 BOOST_CHECK(s.empty());
442 BOOST_CHECK_EQUAL(s.size(), container_type::size_type());
443 BOOST_CHECK_EQUAL(s.size_n(), container_type::size_type());
444 return timed_results_t::value_type(4*1000000/
static_cast<
double>(std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count()))/num_items;
447 #ifdef JMMCG_PERFORMANCE_TESTS
448 stats_to_csv::handle->stats<<timed_results.first.to_csv()<<std::flush;
449 BOOST_CHECK(!timed_results.second);
453 BOOST_AUTO_TEST_SUITE_END()
455 BOOST_AUTO_TEST_SUITE_END()
457 BOOST_AUTO_TEST_SUITE_END()