diff options
Diffstat (limited to 'src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/multi_thread_pass.cpp')
-rw-r--r-- | src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/multi_thread_pass.cpp | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/multi_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/multi_thread_pass.cpp new file mode 100644 index 000000000..703c54f40 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/multi_thread_pass.cpp @@ -0,0 +1,256 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/concurrent_queues/sync_deque.hpp> + +// class sync_deque<T> + +// push || pull; + +#include <boost/config.hpp> +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/concurrent_queues/sync_deque.hpp> +#include <boost/thread/future.hpp> +#include <boost/thread/barrier.hpp> + +#include <boost/detail/lightweight_test.hpp> + +template <typename ValueType> +struct call_push_back +{ + boost::sync_deque<ValueType> *q_; + boost::barrier *go_; + + call_push_back(boost::sync_deque<ValueType> *q, boost::barrier *go) : + q_(q), go_(go) + { + } + typedef void result_type; + void operator()() + { + go_->count_down_and_wait(); + q_->push_back(42); + } +}; + +template <typename ValueType> +struct call_pull_front +{ + boost::sync_deque<ValueType> *q_; + boost::barrier *go_; + + call_pull_front(boost::sync_deque<ValueType> *q, boost::barrier *go) : + q_(q), go_(go) + { + } + typedef ValueType result_type; + ValueType operator()() + { + go_->count_down_and_wait(); + return q_->pull_front(); + } +}; + +template <typename ValueType> +struct call_wait_pull_front +{ + boost::sync_deque<ValueType> *q_; + boost::barrier *go_; + + call_wait_pull_front(boost::sync_deque<ValueType> *q, boost::barrier *go) : + q_(q), go_(go) + { + } + typedef boost::queue_op_status result_type; + boost::queue_op_status operator()(ValueType& v) + { + go_->wait(); + return q_->wait_pull_front(v); + } +}; + +void test_concurrent_push_back_and_pull_front_on_empty_queue() +{ + boost::sync_deque<int> q; + + boost::barrier go(2); + + boost::future<void> push_done; + boost::future<int> pull_done; + + try + { + push_done=boost::async(boost::launch::async, + call_push_back<int>(&q,&go)); + pull_done=boost::async(boost::launch::async, + call_pull_front<int>(&q,&go)); + + push_done.get(); + BOOST_TEST_EQ(pull_done.get(), 42); + BOOST_TEST(q.empty()); + } + catch (...) + { + BOOST_TEST(false); + } +} + +#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +void test_concurrent_push_back_and_wait_pull_front_on_empty_queue() +{ + boost::sync_deque<int> q; + const unsigned int n = 3; + boost::barrier go(n); + + boost::future<boost::queue_op_status> pull_done[n]; + int results[n]; + + try + { + for (unsigned int i =0; i< n; ++i) + pull_done[i]=boost::async(boost::launch::async, + call_wait_pull_front<int>(&q,&go), + boost::ref(results[i])); + + for (unsigned int i =0; i< n; ++i) + q.push_back(42); + + for (unsigned int i = 0; i < n; ++i) { + BOOST_TEST(pull_done[i].get() == boost::queue_op_status::success); + BOOST_TEST_EQ(results[i], 42); + } + BOOST_TEST(q.empty()); + } + catch (...) + { + BOOST_TEST(false); + } +} + +void test_concurrent_wait_pull_front_and_close_on_empty_queue() +{ + boost::sync_deque<int> q; + const unsigned int n = 3; + boost::barrier go(n); + + boost::future<boost::queue_op_status> pull_done[n]; + int results[n]; + + try + { + for (unsigned int i =0; i< n; ++i) + pull_done[i]=boost::async(boost::launch::async, + call_wait_pull_front<int>(&q,&go), + boost::ref(results[i])); + + q.close(); + + for (unsigned int i = 0; i < n; ++i) { + BOOST_TEST(pull_done[i].get() == boost::queue_op_status::closed); + } + BOOST_TEST(q.empty()); + } + catch (...) + { + BOOST_TEST(false); + } +} +#endif + +void test_concurrent_push_back_on_empty_queue() +{ + boost::sync_deque<int> q; + const unsigned int n = 3; + boost::barrier go(n); + boost::future<void> push_done[n]; + + try + { + for (unsigned int i =0; i< n; ++i) + push_done[i]=boost::async(boost::launch::async, + call_push_back<int>(&q,&go)); + + } + catch (...) + { + BOOST_TEST(false); + } + try + { + for (unsigned int i = 0; i < n; ++i) + push_done[i].get(); + + } + catch (...) + { + BOOST_TEST(false); + } + try + { + BOOST_TEST(!q.empty()); + for (unsigned int i =0; i< n; ++i) + BOOST_TEST_EQ(q.pull_front(), 42); + BOOST_TEST(q.empty()); + + } + catch (...) + { + BOOST_TEST(false); + } +} + +void test_concurrent_pull_front_on_queue() +{ + boost::sync_deque<int> q; + const unsigned int n = 3; + boost::barrier go(n); + + boost::future<int> pull_done[n]; + + try + { + for (unsigned int i =0; i< n; ++i) + q.push_back(42); + + for (unsigned int i =0; i< n; ++i) + pull_done[i]=boost::async(boost::launch::async, +#if ! defined BOOST_NO_CXX11_LAMBDAS + [&q,&go]() -> int + { + go.wait(); + return q.pull_front(); + } +#else + call_pull_front<int>(&q,&go) +#endif + ); + + for (unsigned int i = 0; i < n; ++i) + BOOST_TEST_EQ(pull_done[i].get(), 42); + BOOST_TEST(q.empty()); + } + catch (...) + { + BOOST_TEST(false); + } +} + +int main() +{ + test_concurrent_push_back_and_pull_front_on_empty_queue(); +#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + test_concurrent_push_back_and_wait_pull_front_on_empty_queue(); + test_concurrent_wait_pull_front_and_close_on_empty_queue(); +#endif + test_concurrent_push_back_on_empty_queue(); + test_concurrent_pull_front_on_queue(); + return boost::report_errors(); +} + |