21 #define BOOST_TEST_MODULE libjmmcg_tests
22 #include <boost/test/included/unit_test.hpp>
24 #include <boost/mpl/list.hpp>
25 #include <boost/thread/mutex.hpp>
27 #include "core/ave_deviation_meter.hpp"
28 #include "core/stats_output.hpp"
30 #include "core/jthread.hpp"
31 #include "core/thread_wrapper.hpp"
35 using namespace libjmmcg;
43 struct details<api_lock_traits<platform_api, heavyweight_threading>::anon_spin_event_type> {
44 using mutex_t=api_lock_traits<platform_api, heavyweight_threading>::anon_spin_event_type;
45 using lock_t=mutex_t::lock_type;
46 using thread_t=jthread;
50 struct details<api_lock_traits<platform_api, heavyweight_threading>::mutex_type> {
51 using mutex_t=api_lock_traits<platform_api, heavyweight_threading>::mutex_type;
53 using thread_t=jthread;
57 struct details<
std::mutex> {
58 using mutex_t=
std::mutex;
59 using lock_t=std::scoped_lock<mutex_t>;
60 using thread_t=jthread;
65 using lock_t=
boost::mutex::scoped_lock;
66 using thread_t=jthread;
69 using lock_types=boost::mpl::list<
70 details<api_lock_traits<platform_api, heavyweight_threading>::anon_spin_event_type>,
71 details<api_lock_traits<platform_api, heavyweight_threading>::mutex_type>,
76 BOOST_AUTO_TEST_SUITE(mutex_tests)
78 BOOST_AUTO_TEST_CASE(ctor) {
79 using mutex_t=api_lock_traits<platform_api, heavyweight_threading>::anon_spin_event_type;
82 BOOST_CHECK_NO_THROW(lk.lock());
83 BOOST_CHECK_NO_THROW(lk.unlock());
86 BOOST_AUTO_TEST_CASE(scoped_lock) {
87 using mutex_t=api_lock_traits<platform_api, heavyweight_threading>::anon_spin_event_type;
88 using lock_t=mutex_t::lock_type;
91 BOOST_CHECK_NO_THROW(
const lock_t lker(lk));
94 BOOST_AUTO_TEST_CASE(multithreaded_scoped_lock) {
95 using mutex_t=api_lock_traits<platform_api, heavyweight_threading>::anon_spin_event_type;
96 using lock_t=mutex_t::lock_type;
97 using thread_t=jthread;
99 const std::size_t num_loops=1000;
105 for (
std::size_t j=0; j<num_loops; ++j) {
106 const lock_t lker(lk);
113 for (
std::size_t j=0; j<num_loops; ++j) {
114 const lock_t lker(lk);
121 for (
std::size_t j=0; j<num_loops; ++j) {
122 const lock_t lker(lk);
129 for (
std::size_t j=0; j<num_loops; ++j) {
130 const lock_t lker(lk);
136 BOOST_CHECK_EQUAL(i, 4*num_loops);
139 BOOST_AUTO_TEST_SUITE(performance, *stats_to_csv::make_fixture(
"mutex.csv"))
146 BOOST_AUTO_TEST_CASE_TEMPLATE(multithreaded_scoped_lock, details_t, lock_types) {
147 #ifdef JMMCG_PERFORMANCE_TESTS
148 const std::size_t num_tests=5000;
149 const std::size_t num_loops=500000;
151 const std::size_t num_tests=1;
152 const std::size_t num_loops=1000;
155 const std::pair<timed_results_t,
bool> timed_results(compute_average_deviation<timed_results_t::value_type>(
159 using mutex_t=
typename details_t::mutex_t;
160 using lock_t=
typename details_t::lock_t;
161 using thread_t=
typename details_t::thread_t;
165 const std::chrono::high_resolution_clock::time_point t1=std::chrono::high_resolution_clock::now();
169 for (std::size_t j=0; j<num_loops; ++j) {
170 const lock_t lker(lk);
177 for (std::size_t j=0; j<num_loops; ++j) {
178 const lock_t lker(lk);
185 for (std::size_t j=0; j<num_loops; ++j) {
186 const lock_t lker(lk);
193 for (std::size_t j=0; j<num_loops; ++j) {
194 const lock_t lker(lk);
200 const std::chrono::high_resolution_clock::time_point t2=std::chrono::high_resolution_clock::now();
201 BOOST_CHECK_EQUAL(i, 4*num_loops);
202 return timed_results_t::value_type(
static_cast<
double>(std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count())/(4*num_loops));
205 std::cout<<api_threading_traits<platform_api, heavyweight_threading>::demangle_name(
typeid(
typename details_t::mutex_t))<<
" locks-unlock in usec="<<timed_results.first<<std::endl;
206 #ifdef JMMCG_PERFORMANCE_TESTS
207 stats_to_csv::handle->stats<<timed_results.first.to_csv()<<std::flush;
208 BOOST_CHECK(!timed_results.second);
212 BOOST_AUTO_TEST_SUITE_END()
214 BOOST_AUTO_TEST_SUITE_END()