This source file includes following definitions.
- BOOST_AUTO_TEST_SUITE
- BOOST_AUTO_TEST_SUITE_END
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 #include "core/stats_output.hpp"
24
25 #define BOOST_TEST_MODULE libjmmcg_tests
26 #include <boost/test/included/unit_test.hpp>
27
28 #include <boost/test/test_case_template.hpp>
29 #include <boost/mpl/list.hpp>
30
31 #include "core/ave_deviation_meter.hpp"
32 #include "core/unique_ptr.hpp"
33 #include "core/thread_wrapper.hpp"
34
35 #include <boost/move/unique_ptr.hpp>
36
37 #include <chrono>
38
39 using namespace jmmcg;
40 using namespace ppd;
41
42 template<class Mdl>
43 struct obj {
44 using lock_traits=api_lock_traits<platform_api, Mdl>;
45 using element_type=int;
46 using deleter_t=jmmcg::default_delete<obj>;
47
48 element_type const init;
49
50 obj(element_type i) noexcept(true) : init(i) {}
51 ~obj() noexcept(true) {}
52
53 void deleter() {
54 deleter_t().operator()(this);
55 }
56 };
57
58 using ptr_types=boost::mpl::list<
59 std::unique_ptr<obj<heavyweight_threading>>,
60 boost::movelib::unique_ptr<obj<heavyweight_threading>>,
61 unique_ptr<obj<sequential_mode>, api_lock_traits<platform_api, sequential_mode>>,
62 unique_ptr<obj<heavyweight_threading>, api_lock_traits<platform_api, heavyweight_threading>>
63 >;
64 using timed_results_t=ave_deviation_meter<unsigned long long>;
65
66 template<class Element>
67 struct cctor_thread final : public jmmcg::ppd::wrapper<jmmcg::ppd::platform_api, heavyweight_threading> {
68 typedef jmmcg::ppd::wrapper<jmmcg::ppd::platform_api, heavyweight_threading> base_t;
69 typedef std::vector<Element> cont_t;
70 struct make {
71 typename cont_t::value_type::element_type::element_type i;
72
73 make() noexcept(true) : i() {}
74
75 typename cont_t::value_type operator ()() {
76 return typename cont_t::value_type(new typename cont_t::value_type::element_type(++i));
77 }
78 };
79
80 cont_t &cont;
81
82 explicit __stdcall cctor_thread(cont_t &c) noexcept(true)
83 : base_t(), cont(c) {
84 }
85 __stdcall ~cctor_thread() noexcept(true) {
86 this->delete_thread();
87 }
88
89 bool __fastcall worker_fn(typename base_t::thread_context_t &) {
90 while (!cont.empty()) {
91 const typename cont_t::value_type tmp(std::move(cont.back()));
92 cont.pop_back();
93 }
94 return true;
95 }
96 };
97
98 template<class Element>
99 struct dtor_thread final : public jmmcg::ppd::wrapper<jmmcg::ppd::platform_api, heavyweight_threading> {
100 typedef jmmcg::ppd::wrapper<jmmcg::ppd::platform_api, heavyweight_threading> base_t;
101 typedef std::vector<Element> cont_t;
102 struct make {
103 typename cont_t::value_type::element_type::element_type i;
104
105 make() noexcept(true) : i() {}
106
107 typename cont_t::value_type operator ()() {
108 return typename cont_t::value_type(new typename cont_t::value_type::element_type(++i));
109 }
110 };
111
112 cont_t &cont;
113
114 explicit __stdcall dtor_thread(cont_t &c) noexcept(true)
115 : base_t(), cont(c) {
116 }
117 __stdcall ~dtor_thread() noexcept(true) {
118 this->delete_thread();
119 }
120
121 bool __fastcall worker_fn(typename base_t::thread_context_t &) {
122 while (!cont.empty()) {
123 cont.back().reset();
124 cont.pop_back();
125 }
126 return true;
127 }
128 };
129
130 BOOST_AUTO_TEST_SUITE(performance_cctor, *boost::unit_test::fixture<jmmcg::stats_to_csv::wrapper>(std::string("unique_ptr_parallel_cctor.csv")))
131
132 BOOST_AUTO_TEST_SUITE(unique_ptr_parallel_tests)
133
134
135
136
137
138
139 BOOST_AUTO_TEST_CASE_TEMPLATE(parallel_cctor, ptr_t, ptr_types) {
140 typedef cctor_thread<ptr_t> thread_t;
141 #ifdef JMMCG_PERFORMANCE_TESTS
142 const std::size_t num_items=100000000;
143 #else
144 const std::size_t num_items=100;
145 #endif
146 const unsigned short loops_for_conv=50;
147 const double perc_conv_estimate=5.0;
148
149 const std::pair<timed_results_t, bool> timed_results(compute_average_deviation<timed_results_t::value_type>(
150 perc_conv_estimate,
151 loops_for_conv,
152 []() {
153 typename thread_t::cont_t c;
154 std::generate_n(std::back_inserter(c), num_items, typename thread_t::make());
155 thread_t th1(c);
156 thread_t th2(c);
157 c.clear();
158 const auto t1=std::chrono::high_resolution_clock::now();
159 th1.create_running();
160 th2.create_running();
161 do {
162 api_threading_traits<platform_api, heavyweight_threading>::sleep(100);
163 } while (th1.is_running() || th2.is_running());
164 const auto t2=std::chrono::high_resolution_clock::now();
165 BOOST_CHECK(th1.cont.empty());
166 BOOST_CHECK(th2.cont.empty());
167 BOOST_CHECK(c.empty());
168 return timed_results_t::value_type(num_items/(static_cast<double>(std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count())/1000000));
169 }
170 ));
171 std::cout<<typeid(ptr_t).name()<<" rate cctors/sec="<<timed_results.first<<std::endl;
172 #ifdef JMMCG_PERFORMANCE_TESTS
173 stats_to_csv::handle->stats<<timed_results.first.to_csv()<<std::flush;
174 BOOST_CHECK(!timed_results.second);
175 #endif
176 }
177
178 BOOST_AUTO_TEST_SUITE_END()
179
180 BOOST_AUTO_TEST_SUITE(performance_cctor, *boost::unit_test::fixture<jmmcg::stats_to_csv::wrapper>(std::string("unique_ptr_parallel_dtor.csv")))
181
182
183
184
185
186
187 BOOST_AUTO_TEST_CASE_TEMPLATE(parallel_deletes, ptr_t, ptr_types) {
188 typedef dtor_thread<ptr_t> thread_t;
189 #ifdef JMMCG_PERFORMANCE_TESTS
190 const std::size_t num_items=100000000;
191 #else
192 const std::size_t num_items=100;
193 #endif
194 const unsigned short loops_for_conv=50;
195 const double perc_conv_estimate=5.0;
196
197 const std::pair<timed_results_t, bool> timed_results(compute_average_deviation<timed_results_t::value_type>(
198 perc_conv_estimate,
199 loops_for_conv,
200 []() {
201 typename thread_t::cont_t c;
202 std::generate_n(std::back_inserter(c), num_items, typename thread_t::make());
203 thread_t th1(c);
204 thread_t th2(c);
205 c.clear();
206 const auto t1=std::chrono::high_resolution_clock::now();
207 th1.create_running();
208 th2.create_running();
209 do {
210 api_threading_traits<platform_api, heavyweight_threading>::sleep(100);
211 } while (th1.is_running() || th2.is_running());
212 const auto t2=std::chrono::high_resolution_clock::now();
213 BOOST_CHECK(th1.cont.empty());
214 BOOST_CHECK(th2.cont.empty());
215 BOOST_CHECK(c.empty());
216 return timed_results_t::value_type(num_items/(static_cast<double>(std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count())/1000000));
217 }
218 ));
219 std::cout<<typeid(ptr_t).name()<<" rate dtors/sec="<<timed_results.first<<std::endl;
220 #ifdef JMMCG_PERFORMANCE_TESTS
221 stats_to_csv::handle->stats<<timed_results.first.to_csv()<<std::flush;
222 BOOST_CHECK(!timed_results.second);
223 #endif
224 }
225
226 BOOST_AUTO_TEST_SUITE_END()
227
228 BOOST_AUTO_TEST_SUITE_END()