diff options
Diffstat (limited to 'libs/thread/test/sync')
16 files changed, 2502 insertions, 667 deletions
diff --git a/libs/thread/test/sync/futures/async/async_pass.cpp b/libs/thread/test/sync/futures/async/async_pass.cpp index add6282cf..86fdfdbec 100644 --- a/libs/thread/test/sync/futures/async/async_pass.cpp +++ b/libs/thread/test/sync/futures/async/async_pass.cpp @@ -85,7 +85,7 @@ public: return *this; } - int operator()() + int operator()() const { boost::this_thread::sleep_for(ms(200)); return 3; @@ -167,6 +167,48 @@ struct check_timer { int main() { + { + try { + boost::async(f0); + } catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } + { + try { + boost::async(boost::launch::async, f0); + } catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } +#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try { + boost::async(boost::launch::deferred, f0); + } catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } +#endif std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; { try diff --git a/libs/thread/test/sync/futures/future/async_deferred_then_pass.cpp b/libs/thread/test/sync/futures/future/async_deferred_then_pass.cpp index e17e912ce..b400074cd 100644 --- a/libs/thread/test/sync/futures/future/async_deferred_then_pass.cpp +++ b/libs/thread/test/sync/futures/future/async_deferred_then_pass.cpp @@ -53,6 +53,29 @@ int main() { BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; { + try + { + boost::future<int> f1 = boost::async(boost::launch::deferred, &p1); + BOOST_TEST(f1.valid()); + { + boost::future<int> f2 = f1.then(&p2); + BOOST_TEST(f2.valid()); + } + BOOST_TEST(! f1.valid()); + } + catch (std::exception& ex) + { + BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + catch (...) + { + BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { boost::future<int> f1 = boost::async(boost::launch::deferred, &p1); BOOST_TEST(f1.valid()); boost::future<int> f2 = f1.then(&p2); diff --git a/libs/thread/test/sync/futures/future/get_or_pass.cpp b/libs/thread/test/sync/futures/future/get_or_pass.cpp index a2bd65222..64409455b 100644 --- a/libs/thread/test/sync/futures/future/get_or_pass.cpp +++ b/libs/thread/test/sync/futures/future/get_or_pass.cpp @@ -17,6 +17,7 @@ #include <boost/thread/future.hpp> #include <boost/thread/thread.hpp> +#include <boost/core/ref.hpp> #include <boost/detail/lightweight_test.hpp> #if defined BOOST_THREAD_USES_CHRONO @@ -128,49 +129,49 @@ int main() BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; } } -// BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; -// { -// typedef int& T; -// { -// boost::promise<T> p; -// boost::future<T> f = p.get_future(); -//#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) -// boost::thread(func3, boost::move(p)).detach(); -//#else -// int j=5; -// p.set_value(j); -//#endif -// BOOST_TEST(f.valid()); -// int k=4; -// BOOST_TEST(f.get_or(k) == 5); -//#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET -// BOOST_TEST(!f.valid()); -//#endif -// } -// BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; -// { -// boost::promise<T> p; -// boost::future<T> f = p.get_future(); -//#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) -// boost::thread(func4, boost::move(p)).detach(); -//#else -// p.set_exception(boost::make_exception_ptr(3.5)); -//#endif -// try -// { -// BOOST_TEST(f.valid()); -// int j=4; -// BOOST_TEST(f.get_or(j) == 4); -// } -// catch (...) -// { -// BOOST_TEST(false); -// } -//#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET -// BOOST_TEST(!f.valid()); -//#endif -// } -// } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + typedef int& T; + { + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func3, boost::move(p)).detach(); +#else + int j=5; + p.set_value(j); +#endif + BOOST_TEST(f.valid()); + int k=4; + BOOST_TEST(f.get_or(boost::ref(k)) == 5); +#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET + BOOST_TEST(!f.valid()); +#endif + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func4, boost::move(p)).detach(); +#else + p.set_exception(boost::make_exception_ptr(3.5)); +#endif + try + { + BOOST_TEST(f.valid()); + int j=4; + BOOST_TEST(f.get_or(boost::ref(j)) == 4); + } + catch (...) + { + BOOST_TEST(false); + } +#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET + BOOST_TEST(!f.valid()); +#endif + } + } BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; diff --git a/libs/thread/test/sync/futures/make_ready_future_pass.cpp b/libs/thread/test/sync/futures/make_ready_future_pass.cpp new file mode 100644 index 000000000..dfce3cde7 --- /dev/null +++ b/libs/thread/test/sync/futures/make_ready_future_pass.cpp @@ -0,0 +1,157 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011,2014 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/future.hpp> + +// class promise<R> + +// future<void> make_ready_future(); +// template <class T> +// future<decay_t<T>> make_ready_future(T&&); +// template <class T> +// future<T> make_ready_future(remove_reference_t<T>&); +// template <class T> +// future<T> make_ready_future(remove_reference_t<T>&&); +// template <class T, class ...Args> +// future<T> make_ready_future(Args&& ... args); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/static_assert.hpp> + +struct A +{ + A() : + value(0) + { + } + A(int i) : + value(i) + { + } + A(int i, int j) : + value(i+j) + { + } + int value; +}; + +A make(int i) { + return A(i); +} +A make(int i, int j) { + return A(i, j); +} + +struct movable2 +{ + int value_; + BOOST_THREAD_MOVABLE_ONLY(movable2) + movable2() : value_(1){} + movable2(int i) : value_(i){} + movable2(int i, int j) : value_(i+j){} + + //Move constructor and assignment + movable2(BOOST_RV_REF(movable2) m) + { value_ = m.value_; m.value_ = 0; } + + movable2 & operator=(BOOST_THREAD_RV_REF(movable2) m) + { value_ = m.value_; m.value_ = 0; return *this; } + + bool moved() const //Observer + { return !value_; } + + int value() const //Observer + { return value_; } +}; + + +movable2 move_return_function2(int i) { + return movable2(i); +} + +int main() +{ +#if defined BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT((boost::is_copy_constructible<movable2>::value == false)); + BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<movable2>::value == true)); + BOOST_STATIC_ASSERT((boost::is_copy_constructible<A>::value == true)); + BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<A>::value == false)); +#endif + + { + boost::future<void> f = boost::make_ready_future(); + f.wait(); + } + { + typedef A T; + T i; + boost::future<T> f = boost::make_ready_future(i); + BOOST_TEST(f.get().value==0); + } +#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + { + typedef A T; + boost::future<T> f = boost::make_ready_future<T>(); + BOOST_TEST(f.get().value==0); + } + { + typedef A T; + boost::future<T> f = boost::make_ready_future<T>(1); + BOOST_TEST(f.get().value==1); + } + { + typedef A T; + boost::future<T> f = boost::make_ready_future<T>(1,2); + BOOST_TEST(f.get().value==3); + } + { + typedef A T; + T i; + boost::future<T&> f = boost::make_ready_future<T&>(i); + BOOST_TEST(f.get().value==0); + } +#endif +#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +// sync/futures/make_ready_future_pass.cpp:125:65: erreur: conversion from Ôboost::future<boost::rv<movable2> >Õ to non-scalar type Ôboost::future<movable2>Õ requested + { + typedef movable2 T; + T i; + boost::future<T> f = boost::make_ready_future(boost::move(i)); + BOOST_TEST_EQ(f.get().value(),1); + } +#endif +#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + { + typedef movable2 T; + boost::future<T> f = boost::make_ready_future<T>(); + BOOST_TEST(f.get().value()==1); + } + { + typedef movable2 T; + boost::future<T> f = boost::make_ready_future<T>(1); + BOOST_TEST(f.get().value()==1); + } + { + typedef movable2 T; + boost::future<T> f = boost::make_ready_future<T>(1,2); + BOOST_TEST(f.get().value()==3); + } +#endif + + return boost::report_errors(); +} + diff --git a/libs/thread/test/sync/futures/promise/emplace_pass.cpp b/libs/thread/test/sync/futures/promise/emplace_pass.cpp new file mode 100644 index 000000000..6a1a35292 --- /dev/null +++ b/libs/thread/test/sync/futures/promise/emplace_pass.cpp @@ -0,0 +1,207 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011,2014 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/future.hpp> + +// class promise<R> + +// template <class ...Args> +// void promise::emplace(Args&& ... args); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/static_assert.hpp> + +struct A +{ + A() : + value(0) + { + } + A(int i) : + value(i) + { + } + A(int i, int j) : + value(i+j) + { + } + BOOST_THREAD_MOVABLE_ONLY(A) + + A(BOOST_THREAD_RV_REF(A) rhs) + { + if(rhs.value==0) + throw 9; + else + { + value=rhs.value; + rhs.value=0; + } + } + A& operator=(BOOST_THREAD_RV_REF(A) rhs) + { + if(rhs.value==0) + throw 9; + else + { + value=rhs.value; + rhs.value=0; + } + return *this; + } + int value; +}; + +A make(int i) { + return A(i); +} +A make(int i, int j) { + return A(i, j); +} + +struct movable2 +{ + int value_; + BOOST_THREAD_MOVABLE_ONLY(movable2) + movable2() : value_(1){} + movable2(int i) : value_(i){} + movable2(int i, int j) : value_(i+j){} + + //Move constructor and assignment + movable2(BOOST_RV_REF(movable2) m) + { value_ = m.value_; m.value_ = 0; } + + movable2 & operator=(BOOST_THREAD_RV_REF(movable2) m) + { value_ = m.value_; m.value_ = 0; return *this; } + + bool moved() const //Observer + { return !value_; } + + int value() const //Observer + { return value_; } +}; + + +movable2 move_return_function2(int i) { + return movable2(i); +} + +int main() +{ +#if defined BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT((boost::is_copy_constructible<movable2>::value == false)); + BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<movable2>::value == true)); + BOOST_STATIC_ASSERT((boost::is_copy_constructible<A>::value == false)); + BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<A>::value == true)); +#endif +#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + { + typedef A T; + T i; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.emplace(); + try + { + T a = f.get(); (void)a; + BOOST_TEST(false); + } + catch (int j) + { + BOOST_TEST(j == 9); + } + catch (...) + { + BOOST_TEST(false); + } + } + { + typedef A T; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.emplace(3); + BOOST_TEST(f.get().value == 3); + try + { + T j(3); + p.set_value(boost::move(j)); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + + } + { + boost::promise<movable2> p; + boost::future<movable2> f = p.get_future(); + p.emplace(3); + BOOST_TEST(f.get().value_ == 3); + try + { + p.emplace(3); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + + } + { + boost::promise<A> p; + boost::future<A> f = p.get_future(); + p.emplace(1,2); + BOOST_TEST(f.get().value == 3); + try + { + p.emplace(1,2); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + + } + { + typedef A T; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.emplace(3); + boost::promise<T> p2(boost::move(p)); + BOOST_TEST(f.get().value == 3); + + } +#endif + + return boost::report_errors(); +} + diff --git a/libs/thread/test/sync/futures/shared_future/then_pass.cpp b/libs/thread/test/sync/futures/shared_future/then_pass.cpp index 4739135bf..b7d95bc66 100644 --- a/libs/thread/test/sync/futures/shared_future/then_pass.cpp +++ b/libs/thread/test/sync/futures/shared_future/then_pass.cpp @@ -75,6 +75,30 @@ int main() { boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share(); BOOST_TEST(f1.valid()); + boost::future<int> f2 = f1.then(&p2); + boost::future<int> f3 = f1.then(&p2); + BOOST_TEST(f2.valid()); + BOOST_TEST(f3.valid()); + try + { + BOOST_TEST(f2.get()==2); + BOOST_TEST(f3.get()==2); + } + catch (std::exception& ex) + { + BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + catch (...) + { + BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share(); + BOOST_TEST(f1.valid()); boost::future<void> f2 = f1.then(&p3); BOOST_TEST(f2.valid()); try diff --git a/libs/thread/test/sync/mutual_exclusion/deque_views/single_thread_pass.cpp b/libs/thread/test/sync/mutual_exclusion/deque_views/single_thread_pass.cpp new file mode 100644 index 000000000..96e8e268d --- /dev/null +++ b/libs/thread/test/sync/mutual_exclusion/deque_views/single_thread_pass.cpp @@ -0,0 +1,455 @@ +// Copyright (C) 2014 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/sync_deque.hpp> + +// class sync_deque<T> + +// sync_deque(); + +#define BOOST_THREAD_VERSION 4 +//#define BOOST_THREAD_QUEUE_DEPRECATE_OLD + +#include <boost/thread/concurrent_queues/sync_deque.hpp> +#include <boost/thread/concurrent_queues/deque_adaptor.hpp> +#include <boost/thread/concurrent_queues/deque_views.hpp> + +#include <boost/detail/lightweight_test.hpp> +#include <boost/static_assert.hpp> + +class non_copyable +{ + BOOST_THREAD_MOVABLE_ONLY(non_copyable) + int val; +public: + non_copyable(int v) : val(v){} + non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {} + non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; } + bool operator==(non_copyable const& x) const {return val==x.val;} + template <typename OSTREAM> + friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x ) + { + os << x.val; + return os; + } + +}; + +#if defined BOOST_NO_CXX11_RVALUE_REFERENCES +BOOST_STATIC_ASSERT( ! boost::is_copy_constructible<non_copyable>::value ); +BOOST_STATIC_ASSERT( boost::has_move_emulation_enabled<non_copyable>::value ); +#endif + +int main() +{ + + { + // default queue invariants + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // default queue invariants + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + + + { + // empty queue try_pull fails + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + int i; + BOOST_TEST( boost::queue_op_status::empty == q.try_pull(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push rvalue/copyable succeeds + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + q.push(1); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push lvalue/copyable succeeds + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + int i; + q.push(i); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + + +#if 0 + { + // empty queue push rvalue/non_copyable succeeds + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_back<non_copyable> q(sq); + q.push(non_copyable(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + { + // empty queue push rvalue/non_copyable succeeds + boost::deque_adaptor<boost::sync_deque<non_copyable> > q; + //boost::sync_deque<non_copyable> q; + //boost::deque_back<non_copyable> q(sq); + non_copyable nc(1); + q.push_back(boost::move(nc)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + + { + // empty queue push rvalue succeeds + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + q.push(1); + q.push(2); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 2u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push lvalue succeeds + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + int i; + q.push(i); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue/copyable succeeds + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + BOOST_TEST(boost::queue_op_status::success == q.try_push(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue/copyable succeeds + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + BOOST_TEST(boost::queue_op_status::success == q.try_push(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + +#if 0 + { + // empty queue try_push rvalue/non-copyable succeeds + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_back<non_copyable> q(sq); + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.try_push(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + + { + // empty queue try_push lvalue succeeds + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + int i; + BOOST_TEST(boost::queue_op_status::success == q.try_push(i)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue succeeds + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + + +#if 0 + { + // empty queue nonblocking_push_back rvalue/non-copyable succeeds + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_back<non_copyable> q(sq); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(non_copyable(1))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + { + // empty queue nonblocking_push_back rvalue/non-copyable succeeds + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_back<non_copyable> q(sq); + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull_front succeed + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + sq.push_back(1); + int i; + q.pull(i); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull_front succeed + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_front<non_copyable> q(sq); + non_copyable nc1(1); + sq.push_back(boost::move(nc1)); + non_copyable nc2(2); + q.pull(nc2); + BOOST_TEST_EQ(nc1, nc2); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull_front succeed + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + sq.push_back(1); + int i = q.pull(); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull_front succeed + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_front<non_copyable> q(sq); + non_copyable nc1(1); + sq.push_back(boost::move(nc1)); + non_copyable nc = q.pull(); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue try_pull_front succeed + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + sq.push_back(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.try_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue try_pull_front succeed + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_front<non_copyable> q(sq); + non_copyable nc1(1); + sq.push_back(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.try_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue nonblocking_pull_front succeed + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + sq.push_back(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue nonblocking_pull_front succeed + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_front<non_copyable> q(sq); + non_copyable nc1(1); + sq.push_back(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue wait_pull_front succeed + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_front<non_copyable> q(sq); + non_copyable nc1(1); + sq.push_back(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue wait_pull_front succeed + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + sq.push_back(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue wait_pull_front succeed + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_front<non_copyable> q(sq); + non_copyable nc1(1); + sq.push_back(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + + { + // closed invariants + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed invariants + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed queue push fails + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + q.close(); + try { + q.push(1); + BOOST_TEST(false); + } catch (...) { + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + } + { + // 1-element closed queue pull succeed + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + sq.push_back(1); + q.close(); + int i; + q.pull(i); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // 1-element closed queue wait_pull_front succeed + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + sq.push_back(1); + q.close(); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed empty queue wait_pull_front fails + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + int i; + BOOST_TEST(boost::queue_op_status::closed == q.wait_pull(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + } + return boost::report_errors(); +} + diff --git a/libs/thread/test/sync/mutual_exclusion/queue_views/single_thread_pass.cpp b/libs/thread/test/sync/mutual_exclusion/queue_views/single_thread_pass.cpp index 141c23a4f..41cf1cf3a 100644 --- a/libs/thread/test/sync/mutual_exclusion/queue_views/single_thread_pass.cpp +++ b/libs/thread/test/sync/mutual_exclusion/queue_views/single_thread_pass.cpp @@ -12,7 +12,7 @@ #define BOOST_THREAD_VERSION 4 //#define BOOST_THREAD_QUEUE_DEPRECATE_OLD -#include <boost/thread/sync_queue.hpp> +#include <boost/thread/concurrent_queues/sync_queue.hpp> #include <boost/thread/concurrent_queues/queue_adaptor.hpp> #include <boost/thread/concurrent_queues/queue_views.hpp> @@ -117,7 +117,7 @@ int main() //boost::sync_queue<non_copyable> q; //boost::queue_back<non_copyable> q(sq); non_copyable nc(1); - q.push_back(boost::move(nc)); + q.push(boost::move(nc)); BOOST_TEST(! q.empty()); BOOST_TEST(! q.full()); BOOST_TEST_EQ(q.size(), 1u); @@ -206,7 +206,7 @@ int main() #if 0 { - // empty queue nonblocking_push_back rvalue/non-copyable succeeds + // empty queue nonblocking_push rvalue/non-copyable succeeds boost::queue_adaptor<boost::sync_queue<non_copyable> > sq; boost::queue_back<non_copyable> q(sq); BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(non_copyable(1))); @@ -217,7 +217,7 @@ int main() } #endif { - // empty queue nonblocking_push_back rvalue/non-copyable succeeds + // empty queue nonblocking_push rvalue/non-copyable succeeds boost::queue_adaptor<boost::sync_queue<non_copyable> > sq; boost::queue_back<non_copyable> q(sq); non_copyable nc(1); @@ -228,10 +228,10 @@ int main() BOOST_TEST(! q.closed()); } { - // 1-element queue pull_front succeed + // 1-element queue pull succeed boost::queue_adaptor<boost::sync_queue<int> > sq; boost::queue_front<int> q(sq); - sq.push_back(1); + sq.push(1); int i; q.pull(i); BOOST_TEST_EQ(i, 1); @@ -241,11 +241,11 @@ int main() BOOST_TEST(! q.closed()); } { - // 1-element queue pull_front succeed + // 1-element queue pull succeed boost::queue_adaptor<boost::sync_queue<non_copyable> > sq; boost::queue_front<non_copyable> q(sq); non_copyable nc1(1); - sq.push_back(boost::move(nc1)); + sq.push(boost::move(nc1)); non_copyable nc2(2); q.pull(nc2); BOOST_TEST_EQ(nc1, nc2); @@ -255,10 +255,10 @@ int main() BOOST_TEST(! q.closed()); } { - // 1-element queue pull_front succeed + // 1-element queue pull succeed boost::queue_adaptor<boost::sync_queue<int> > sq; boost::queue_front<int> q(sq); - sq.push_back(1); + sq.push(1); int i = q.pull(); BOOST_TEST_EQ(i, 1); BOOST_TEST(q.empty()); @@ -267,11 +267,11 @@ int main() BOOST_TEST(! q.closed()); } { - // 1-element queue pull_front succeed + // 1-element queue pull succeed boost::queue_adaptor<boost::sync_queue<non_copyable> > sq; boost::queue_front<non_copyable> q(sq); non_copyable nc1(1); - sq.push_back(boost::move(nc1)); + sq.push(boost::move(nc1)); non_copyable nc = q.pull(); BOOST_TEST_EQ(nc, nc1); BOOST_TEST(q.empty()); @@ -280,10 +280,10 @@ int main() BOOST_TEST(! q.closed()); } { - // 1-element queue try_pull_front succeed + // 1-element queue try_pull succeed boost::queue_adaptor<boost::sync_queue<int> > sq; boost::queue_front<int> q(sq); - sq.push_back(1); + sq.push(1); int i; BOOST_TEST(boost::queue_op_status::success == q.try_pull(i)); BOOST_TEST_EQ(i, 1); @@ -293,11 +293,11 @@ int main() BOOST_TEST(! q.closed()); } { - // 1-element queue try_pull_front succeed + // 1-element queue try_pull succeed boost::queue_adaptor<boost::sync_queue<non_copyable> > sq; boost::queue_front<non_copyable> q(sq); non_copyable nc1(1); - sq.push_back(boost::move(nc1)); + sq.push(boost::move(nc1)); non_copyable nc(2); BOOST_TEST(boost::queue_op_status::success == q.try_pull(nc)); BOOST_TEST_EQ(nc, nc1); @@ -307,10 +307,10 @@ int main() BOOST_TEST(! q.closed()); } { - // 1-element queue nonblocking_pull_front succeed + // 1-element queue nonblocking_pull succeed boost::queue_adaptor<boost::sync_queue<int> > sq; boost::queue_front<int> q(sq); - sq.push_back(1); + sq.push(1); int i; BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(i)); BOOST_TEST_EQ(i, 1); @@ -320,11 +320,11 @@ int main() BOOST_TEST(! q.closed()); } { - // 1-element queue nonblocking_pull_front succeed + // 1-element queue nonblocking_pull succeed boost::queue_adaptor<boost::sync_queue<non_copyable> > sq; boost::queue_front<non_copyable> q(sq); non_copyable nc1(1); - sq.push_back(boost::move(nc1)); + sq.push(boost::move(nc1)); non_copyable nc(2); BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(nc)); BOOST_TEST_EQ(nc, nc1); @@ -334,11 +334,11 @@ int main() BOOST_TEST(! q.closed()); } { - // 1-element queue wait_pull_front succeed + // 1-element queue wait_pull succeed boost::queue_adaptor<boost::sync_queue<non_copyable> > sq; boost::queue_front<non_copyable> q(sq); non_copyable nc1(1); - sq.push_back(boost::move(nc1)); + sq.push(boost::move(nc1)); non_copyable nc(2); BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc)); BOOST_TEST_EQ(nc, nc1); @@ -348,10 +348,10 @@ int main() BOOST_TEST(! q.closed()); } { - // 1-element queue wait_pull_front succeed + // 1-element queue wait_pull succeed boost::queue_adaptor<boost::sync_queue<int> > sq; boost::queue_front<int> q(sq); - sq.push_back(1); + sq.push(1); int i; BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i)); BOOST_TEST_EQ(i, 1); @@ -361,11 +361,11 @@ int main() BOOST_TEST(! q.closed()); } { - // 1-element queue wait_pull_front succeed + // 1-element queue wait_pull succeed boost::queue_adaptor<boost::sync_queue<non_copyable> > sq; boost::queue_front<non_copyable> q(sq); non_copyable nc1(1); - sq.push_back(boost::move(nc1)); + sq.push(boost::move(nc1)); non_copyable nc(2); BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc)); BOOST_TEST_EQ(nc, nc1); @@ -414,7 +414,7 @@ int main() // 1-element closed queue pull succeed boost::queue_adaptor<boost::sync_queue<int> > sq; boost::queue_front<int> q(sq); - sq.push_back(1); + sq.push(1); q.close(); int i; q.pull(i); @@ -425,10 +425,10 @@ int main() BOOST_TEST(q.closed()); } { - // 1-element closed queue wait_pull_front succeed + // 1-element closed queue wait_pull succeed boost::queue_adaptor<boost::sync_queue<int> > sq; boost::queue_front<int> q(sq); - sq.push_back(1); + sq.push(1); q.close(); int i; BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i)); @@ -439,7 +439,7 @@ int main() BOOST_TEST(q.closed()); } { - // closed empty queue wait_pull_front fails + // closed empty queue wait_pull fails boost::queue_adaptor<boost::sync_queue<int> > sq; boost::queue_front<int> q(sq); q.close(); diff --git a/libs/thread/test/sync/mutual_exclusion/sync_deque/multi_thread_pass.cpp b/libs/thread/test/sync/mutual_exclusion/sync_deque/multi_thread_pass.cpp new file mode 100644 index 000000000..703c54f40 --- /dev/null +++ b/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(); +} + diff --git a/libs/thread/test/sync/mutual_exclusion/sync_deque/single_thread_pass.cpp b/libs/thread/test/sync/mutual_exclusion/sync_deque/single_thread_pass.cpp new file mode 100644 index 000000000..5170bcf61 --- /dev/null +++ b/libs/thread/test/sync/mutual_exclusion/sync_deque/single_thread_pass.cpp @@ -0,0 +1,403 @@ +// Copyright (C) 2013,2015 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> + +// sync_deque(); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/concurrent_queues/sync_deque.hpp> + +#include <boost/detail/lightweight_test.hpp> + +class non_copyable +{ + BOOST_THREAD_MOVABLE_ONLY(non_copyable) + int val; +public: + non_copyable(int v) : val(v){} + non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {} + non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; } + bool operator==(non_copyable const& x) const {return val==x.val;} + template <typename OSTREAM> + friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x ) + { + os << x.val; + return os; + } + +}; + + + +int main() +{ + + { + // default queue invariants + boost::sync_deque<int> q; + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_pull fails + boost::sync_deque<int> q; + int i; + BOOST_TEST( boost::queue_op_status::empty == q.try_pull_front(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push rvalue/copyable succeeds + boost::sync_deque<int> q; + q.push_back(1); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push lvalue/copyable succeeds + boost::sync_deque<int> q; + int i; + q.push_back(i); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + { + // empty queue push rvalue/non_copyable succeeds + boost::sync_deque<non_copyable> q; + q.push_back(non_copyable(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + { + // empty queue push rvalue/non_copyable succeeds + boost::sync_deque<non_copyable> q; + non_copyable nc(1); + q.push_back(boost::move(nc)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + + { + // empty queue push rvalue succeeds + boost::sync_deque<int> q; + q.push_back(1); + q.push_back(2); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 2u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push lvalue succeeds + boost::sync_deque<int> q; + int i; + q.push_back(i); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue/copyable succeeds + boost::sync_deque<int> q; + BOOST_TEST(boost::queue_op_status::success == q.try_push_back(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue/copyable succeeds + boost::sync_deque<int> q; + BOOST_TEST(boost::queue_op_status::success == q.try_push_back(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + { + // empty queue try_push rvalue/non-copyable succeeds + boost::sync_deque<non_copyable> q; + BOOST_TEST(boost::queue_op_status::success ==q.try_push_back(non_copyable(1))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + { + // empty queue try_push rvalue/non-copyable succeeds + boost::sync_deque<non_copyable> q; + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.try_push_back(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + + { + // empty queue try_push lvalue succeeds + boost::sync_deque<int> q; + int i=1; + BOOST_TEST(boost::queue_op_status::success == q.try_push_back(i)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue succeeds + boost::sync_deque<int> q; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + { + // empty queue nonblocking_push_back rvalue/non-copyable succeeds + boost::sync_deque<non_copyable> q; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(non_copyable(1))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + { + // empty queue nonblocking_push_back rvalue/non-copyable succeeds + boost::sync_deque<non_copyable> q; + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull_front succeed + boost::sync_deque<int> q; + q.push_back(1); + int i; + q.pull_front(i); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull_front succeed + boost::sync_deque<non_copyable> q; + non_copyable nc1(1); + q.push_back(boost::move(nc1)); + non_copyable nc2(2); + q.pull_front(nc2); + BOOST_TEST_EQ(nc1, nc2); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull_front succeed + boost::sync_deque<int> q; + q.push_back(1); + int i = q.pull_front(); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull_front succeed + boost::sync_deque<non_copyable> q; + non_copyable nc1(1); + q.push_back(boost::move(nc1)); + non_copyable nc = q.pull_front(); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue try_pull_front succeed + boost::sync_deque<int> q; + q.push_back(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.try_pull_front(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue try_pull_front succeed + boost::sync_deque<non_copyable> q; + non_copyable nc1(1); + q.push_back(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.try_pull_front(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue nonblocking_pull_front succeed + boost::sync_deque<int> q; + q.push_back(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull_front(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue nonblocking_pull_front succeed + boost::sync_deque<non_copyable> q; + non_copyable nc1(1); + q.push_back(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull_front(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue wait_pull_front succeed + boost::sync_deque<non_copyable> q; + non_copyable nc1(1); + q.push_back(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue wait_pull_front succeed + boost::sync_deque<int> q; + q.push_back(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue wait_pull_front succeed + boost::sync_deque<non_copyable> q; + non_copyable nc1(1); + q.push_back(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + + { + // closed invariants + boost::sync_deque<int> q; + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed queue push fails + boost::sync_deque<int> q; + q.close(); + try { + q.push_back(1); + BOOST_TEST(false); + } catch (...) { + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + } + { + // 1-element closed queue pull succeed + boost::sync_deque<int> q; + q.push_back(1); + q.close(); + int i; + q.pull_front(i); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // 1-element closed queue wait_pull_front succeed + boost::sync_deque<int> q; + q.push_back(1); + q.close(); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed empty queue wait_pull_front fails + boost::sync_deque<int> q; + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + int i; + BOOST_TEST(boost::queue_op_status::closed == q.wait_pull_front(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + } + + return boost::report_errors(); +} + diff --git a/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_multi_thread_pass.cpp b/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_multi_thread_pass.cpp new file mode 100644 index 000000000..d8e82c2e6 --- /dev/null +++ b/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_multi_thread_pass.cpp @@ -0,0 +1,215 @@ +// Copyright (C) 2014 Ian Forbed +// Copyright (C) 2014 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) +// + +#include <boost/config.hpp> +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + +#define BOOST_THREAD_VERSION 4 +#define BOOST_THREAD_PROVIDES_EXECUTORS + +#include <exception> + +#include <boost/thread/thread.hpp> +#include <boost/thread/barrier.hpp> +#include <boost/thread/concurrent_queues/sync_priority_queue.hpp> + +#include <boost/core/lightweight_test.hpp> + +typedef boost::concurrent::sync_priority_queue<int> sync_pq; + +int call_pull(sync_pq* q, boost::barrier* go) +{ + go->wait(); + return q->pull(); + +} + +void call_push(sync_pq* q, boost::barrier* go, int val) +{ + go->wait(); + q->push(val); +} + +void test_pull(const int n) +{ + sync_pq pq; + BOOST_TEST(pq.empty()); + for(int i = 0; i < n; i++) + { + pq.push(i); + } + BOOST_TEST(!pq.empty()); + BOOST_TEST_EQ(pq.size(), std::size_t(n)); + pq.close(); + BOOST_TEST(pq.closed()); + boost::barrier b(n); + boost::thread_group tg; + for(int i = 0; i < n; i++) + { + tg.create_thread(boost::bind(call_pull, &pq, &b)); + } + tg.join_all(); + BOOST_TEST(pq.empty()); +} + +void test_push(const int n) +{ + sync_pq pq; + BOOST_TEST(pq.empty()); + + boost::barrier b(n); + boost::thread_group tg; + for(int i = 0; i < n; i++) + { + tg.create_thread(boost::bind(call_push, &pq, &b, i)); + } + tg.join_all(); + BOOST_TEST(!pq.empty()); + BOOST_TEST_EQ(pq.size(), std::size_t(n)); +} + +void test_both(const int n) +{ + sync_pq pq; + BOOST_TEST(pq.empty()); + + boost::barrier b(2*n); + boost::thread_group tg; + for(int i = 0; i < n; i++) + { + tg.create_thread(boost::bind(call_pull, &pq, &b)); + tg.create_thread(boost::bind(call_push, &pq, &b, i)); + } + tg.join_all(); + BOOST_TEST(pq.empty()); + BOOST_TEST_EQ(pq.size(), std::size_t(0)); +} + +void push_range(sync_pq* q, const int begin, const int end) +{ + for(int i = begin; i < end; i++) + q->push(i); +} + +void atomic_pull(sync_pq* q, boost::atomic<int>* sum) +{ + while(1) + { + try{ + const int val = q->pull(); + sum->fetch_add(val); + } + catch(std::exception& e ){ + break; + } + } +} + +/** + * This test computes the sum of the first N integers upto $limit using + * $n threads for the push operation and $n threads for the pull and count + * operation. The push operation push a range of numbers on the queue while + * the pull operation pull from the queue and increments an atomic int. + * At the end of execution the value of atomic<int> $sum should be the same + * as n*(n+1)/2 as this is the closed form solution to this problem. + */ +void compute_sum(const int n) +{ + const int limit = 1000; + sync_pq pq; + BOOST_TEST(pq.empty()); + boost::atomic<int> sum(0); + boost::thread_group tg1; + boost::thread_group tg2; + for(int i = 0; i < n; i++) + { + tg1.create_thread(boost::bind(push_range, &pq, i*(limit/n)+1, (i+1)*(limit/n)+1)); + tg2.create_thread(boost::bind(atomic_pull, &pq, &sum)); + } + tg1.join_all(); + pq.close(); //Wait until all enqueuing is done before closing. + BOOST_TEST(pq.closed()); + tg2.join_all(); + BOOST_TEST(pq.empty()); + BOOST_TEST_EQ(sum.load(), limit*(limit+1)/2); +} + +void move_between_queues(sync_pq* q1, sync_pq* q2) +{ + while(1){ + try{ + const int val = q1->pull(); + q2->push(val); + } + catch(std::exception& e){ + break; + } + } +} + +/** + * This test computes the sum of the first N integers upto $limit by moving + * numbers between 2 sync_priority_queues. A range of numbers are pushed onto + * one queue by $n threads while $n threads pull from this queue and push onto + * another sync_pq. At the end the main thread ensures the the values in the + * second queue are in proper order and then sums all the values from this + * queue. The sum should match n*(n+1)/2, the closed form solution to this + * problem. + */ +void sum_with_moving(const int n) +{ + const int limit = 1000; + sync_pq pq1; + sync_pq pq2; + BOOST_TEST(pq1.empty()); + BOOST_TEST(pq2.empty()); + boost::thread_group tg1; + boost::thread_group tg2; + for(int i = 0; i < n; i++) + { + tg1.create_thread(boost::bind(push_range, &pq1, i*(limit/n)+1, (i+1)*(limit/n)+1)); + tg2.create_thread(boost::bind(move_between_queues, &pq1, &pq2)); + } + tg1.join_all(); + pq1.close(); //Wait until all enqueuing is done before closing. + BOOST_TEST(pq1.closed()); + tg2.join_all(); + BOOST_TEST(pq1.empty()); + BOOST_TEST(!pq2.empty()); + int sum = 0; + for(int i = 1000; i > 0; i--){ + const int val = pq2.pull(); + BOOST_TEST_EQ(i,val); + sum += val; + } + BOOST_TEST(pq2.empty()); + BOOST_TEST_EQ(sum, limit*(limit+1)/2); +} + +int main() +{ + for(int i = 1; i <= 64; i *= 2) + { + test_pull(i); + test_push(i); + test_both(i); + } + //These numbers must divide 1000 + compute_sum(1); + compute_sum(4); + compute_sum(10); + compute_sum(25); + compute_sum(50); + sum_with_moving(1); + sum_with_moving(4); + sum_with_moving(10); + sum_with_moving(25); + sum_with_moving(50); + return boost::report_errors(); +} diff --git a/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_single_thread_pass.cpp b/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_single_thread_pass.cpp new file mode 100644 index 000000000..cc1ae90c6 --- /dev/null +++ b/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_single_thread_pass.cpp @@ -0,0 +1,425 @@ +// Copyright (C) 2014 Ian Forbed +// Copyright (C) 2014,2015 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) +// + +#include <boost/config.hpp> +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + +#define BOOST_THREAD_VERSION 4 +#define BOOST_THREAD_PROVIDES_EXECUTORS + +#include <iostream> + +#include <boost/thread.hpp> +#include <boost/chrono.hpp> +#include <boost/thread/concurrent_queues/sync_priority_queue.hpp> + +#include <boost/detail/lightweight_test.hpp> + +using namespace boost::chrono; + +typedef boost::concurrent::sync_priority_queue<int> sync_pq; + +class non_copyable +{ + BOOST_THREAD_MOVABLE_ONLY(non_copyable) + int val; +public: + non_copyable(int v) : val(v){} + non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {} + non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; } + bool operator==(non_copyable const& x) const {return val==x.val;} + template <typename OSTREAM> + friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x ) + { + os << x.val; + return os; + } + bool operator <(const non_copyable& other) const + { + return val < other.val; + } +}; + + +void test_pull_for() +{ + sync_pq pq; + steady_clock::time_point start = steady_clock::now(); + int val; + boost::queue_op_status st = pq.pull_for(milliseconds(500), val); + steady_clock::duration diff = steady_clock::now() - start; + BOOST_TEST(boost::queue_op_status::timeout == st); + BOOST_TEST(diff < milliseconds(550) && diff > milliseconds(500)); +} + +void test_pull_until() +{ + sync_pq pq; + steady_clock::time_point start = steady_clock::now(); + int val; + boost::queue_op_status st = pq.pull_until(start + milliseconds(500), val); + steady_clock::duration diff = steady_clock::now() - start; + BOOST_TEST(boost::queue_op_status::timeout == st); + BOOST_TEST(diff < milliseconds(550) && diff > milliseconds(500)); +} + +void test_nonblocking_pull() +{ + sync_pq pq; + steady_clock::time_point start = steady_clock::now(); + int val; + boost::queue_op_status st = pq.nonblocking_pull(val); + steady_clock::duration diff = steady_clock::now() - start; + BOOST_TEST(boost::queue_op_status::empty == st); + BOOST_TEST(diff < milliseconds(5)); +} + +void test_pull_for_when_not_empty() +{ + sync_pq pq; + pq.push(1); + steady_clock::time_point start = steady_clock::now(); + int val; + boost::queue_op_status st = pq.pull_for(milliseconds(500), val); + steady_clock::duration diff = steady_clock::now() - start; + BOOST_TEST(boost::queue_op_status::success == st); + BOOST_TEST(1 == val); + BOOST_TEST(diff < milliseconds(5)); +} + +void test_pull_until_when_not_empty() +{ + sync_pq pq; + pq.push(1); + steady_clock::time_point start = steady_clock::now(); + int val; + boost::queue_op_status st = pq.pull_until(start + milliseconds(500), val); + steady_clock::duration diff = steady_clock::now() - start; + BOOST_TEST(boost::queue_op_status::success == st); + BOOST_TEST(1 == val); + BOOST_TEST(diff < milliseconds(5)); +} + +int main() +{ + sync_pq pq; + BOOST_TEST(pq.empty()); + BOOST_TEST(!pq.closed()); + BOOST_TEST_EQ(pq.size(), std::size_t(0)); + + for(int i = 1; i <= 5; i++){ + pq.push(i); + BOOST_TEST(!pq.empty()); + BOOST_TEST_EQ(pq.size(), std::size_t(i)); + } + + for(int i = 6; i <= 10; i++){ + boost::queue_op_status succ = pq.try_push(i); + BOOST_TEST(succ == boost::queue_op_status::success ); + BOOST_TEST(!pq.empty()); + BOOST_TEST_EQ(pq.size(), std::size_t(i)); + } + + for(int i = 10; i > 5; i--){ + int val = pq.pull(); + BOOST_TEST_EQ(val, i); + } + +// for(int i = 5; i > 0; i--){ +// boost::optional<int> val = pq.try_pull(); +// BOOST_TEST(val); +// BOOST_TEST_EQ(*val, i); +// } + +// BOOST_TEST(pq.empty()); + pq.close(); + BOOST_TEST(pq.closed()); + + test_pull_for(); + test_pull_until(); + test_nonblocking_pull(); + + test_pull_for_when_not_empty(); + //test_pull_until_when_not_empty(); + +#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES + { + // empty queue try_push rvalue/non-copyable succeeds + boost::concurrent::sync_priority_queue<non_copyable> q; + BOOST_TEST(boost::queue_op_status::success ==q.try_push(non_copyable(1))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + //fixme + // empty queue try_push rvalue/non-copyable succeeds + boost::concurrent::sync_priority_queue<non_copyable> q; + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.try_push(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + + { + // empty queue try_push lvalue succeeds + boost::concurrent::sync_priority_queue<int> q; + int i=1; + BOOST_TEST(boost::queue_op_status::success == q.try_push(i)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#if 0 + { + // empty queue try_push rvalue succeeds + boost::concurrent::sync_priority_queue<int> q; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue nonblocking_push rvalue/non-copyable succeeds + boost::concurrent::sync_priority_queue<non_copyable> q; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(non_copyable(1))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue nonblocking_push rvalue/non-copyable succeeds + boost::concurrent::sync_priority_queue<non_copyable> q; + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + + { + // 1-element queue pull succeed + boost::concurrent::sync_priority_queue<int> q; + q.push(1); + int i; + i=q.pull(); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES + { + // 1-element queue pull succeed + boost::concurrent::sync_priority_queue<non_copyable> q; + non_copyable nc1(1); + q.push(boost::move(nc1)); + non_copyable nc2(2); + nc2=q.pull(); + BOOST_TEST_EQ(nc1, nc2); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + + { + // 1-element queue pull succeed + boost::concurrent::sync_priority_queue<int> q; + q.push(1); + int i = q.pull(); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES + { + // 1-element queue pull succeed + boost::concurrent::sync_priority_queue<non_copyable> q; + non_copyable nc1(1); + q.push(boost::move(nc1)); + non_copyable nc = q.pull(); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + + { + // 1-element queue try_pull succeed + boost::concurrent::sync_priority_queue<int> q; + q.push(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.try_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES + { + // 1-element queue try_pull succeed + boost::concurrent::sync_priority_queue<non_copyable> q; + non_copyable nc1(1); + q.push(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.try_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + { + // 1-element queue nonblocking_pull succeed + boost::concurrent::sync_priority_queue<int> q; + q.push(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES + { + // 1-element queue nonblocking_pull succeed + boost::concurrent::sync_priority_queue<non_copyable> q; + non_copyable nc1(1); + q.push(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue wait_pull succeed + boost::concurrent::sync_priority_queue<non_copyable> q; + non_copyable nc1(1); + q.push(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + { + // 1-element queue wait_pull succeed + boost::concurrent::sync_priority_queue<int> q; + q.push(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES + { + // 1-element queue wait_pull succeed + boost::concurrent::sync_priority_queue<non_copyable> q; + non_copyable nc1(1); + q.push(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + + { + // closed invariants + boost::concurrent::sync_priority_queue<int> q; + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed queue push fails + boost::concurrent::sync_priority_queue<int> q; + q.close(); + try { + q.push(1); + BOOST_TEST(false); // fixme + } catch (...) { + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + } + { + // 1-element closed queue pull succeed + boost::concurrent::sync_priority_queue<int> q; + q.push(1); + q.close(); + int i; + i=q.pull(); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // 1-element closed queue wait_pull succeed + boost::concurrent::sync_priority_queue<int> q; + q.push(1); + q.close(); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed empty queue wait_pull fails + boost::concurrent::sync_priority_queue<int> q; + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + int i; + BOOST_TEST(boost::queue_op_status::closed == q.wait_pull(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + } + return boost::report_errors(); +} diff --git a/libs/thread/test/sync/mutual_exclusion/sync_pq/tq_single_thread_pass.cpp b/libs/thread/test/sync/mutual_exclusion/sync_pq/tq_single_thread_pass.cpp new file mode 100644 index 000000000..dd4dfc17f --- /dev/null +++ b/libs/thread/test/sync/mutual_exclusion/sync_pq/tq_single_thread_pass.cpp @@ -0,0 +1,155 @@ +// Copyright (C) 2014 Ian Forbed +// Copyright (C) 2014 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) +// + +#include <boost/config.hpp> +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + +#define BOOST_THREAD_VERSION 4 +#define BOOST_THREAD_PROVIDES_EXECUTORS + +#include <boost/thread.hpp> +#include <boost/chrono.hpp> +#include <boost/function.hpp> +#include <boost/thread/concurrent_queues/sync_timed_queue.hpp> +#include <boost/thread/executors/work.hpp> + +#include <boost/core/lightweight_test.hpp> + +using namespace boost::chrono; + +typedef boost::concurrent::sync_timed_queue<int> sync_tq; + +void test_all() +{ + sync_tq pq; + BOOST_TEST(pq.empty()); + BOOST_TEST(!pq.closed()); + BOOST_TEST_EQ(pq.size(), std::size_t(0)); + + for(int i = 1; i <= 5; i++){ + pq.push(i, milliseconds(i*100)); + BOOST_TEST(!pq.empty()); + BOOST_TEST_EQ(pq.size(), std::size_t(i)); + } + + for(int i = 6; i <= 10; i++){ + pq.push(i,steady_clock::now() + milliseconds(i*100)); + BOOST_TEST(!pq.empty()); + BOOST_TEST_EQ(pq.size(), std::size_t(i)); + } + + for(int i = 1; i <= 10; i++){ + int val = pq.pull(); + BOOST_TEST_EQ(val, i); + } + + int val; + boost::queue_op_status st = pq.nonblocking_pull(val); + BOOST_TEST(boost::queue_op_status::empty == st); + + BOOST_TEST(pq.empty()); + pq.close(); + BOOST_TEST(pq.closed()); +} + +void test_all_with_try() +{ + sync_tq pq; + BOOST_TEST(pq.empty()); + BOOST_TEST(!pq.closed()); + BOOST_TEST_EQ(pq.size(), std::size_t(0)); + + for(int i = 1; i <= 5; i++){ + boost::queue_op_status st = pq.try_push(i, milliseconds(i*100)); + BOOST_TEST(st == boost::queue_op_status::success ); + BOOST_TEST(!pq.empty()); + BOOST_TEST_EQ(pq.size(), std::size_t(i)); + } + + for(int i = 6; i <= 10; i++){ + boost::queue_op_status st = pq.try_push(i,steady_clock::now() + milliseconds(i*100)); + BOOST_TEST(st == boost::queue_op_status::success ); + BOOST_TEST(!pq.empty()); + BOOST_TEST_EQ(pq.size(), std::size_t(i)); + } + + for(int i = 1; i <= 10; i++){ + int val=0; + boost::queue_op_status st = pq.wait_pull(val); + BOOST_TEST(st == boost::queue_op_status::success ); + BOOST_TEST_EQ(val, i); + } + + int val; + boost::queue_op_status st = pq.nonblocking_pull(val); + BOOST_TEST(st == boost::queue_op_status::empty ); + + BOOST_TEST(pq.empty()); + pq.close(); + BOOST_TEST(pq.closed()); +} + +void func(steady_clock::time_point pushed, steady_clock::duration dur) +{ + BOOST_TEST(pushed + dur <= steady_clock::now()); +} +void func2() +{ + BOOST_TEST(false); +} + +/** + * This test ensures that when items come of the front of the queue + * that at least $dur has elapsed. + */ +void test_deque_times() +{ + boost::concurrent::sync_timed_queue<boost::function<void()> > tq; + for(int i = 0; i < 10; i++) + { + steady_clock::duration d = milliseconds(i*100); + boost::function<void()> fn = boost::bind(func, steady_clock::now(), d); + tq.push(fn, d); + } + while(!tq.empty()) + { + boost::function<void()> fn = tq.pull(); + fn(); + } +} + +/** + * This test ensures that when items come of the front of the queue + * that at least $dur has elapsed. + */ +#if 0 +void test_deque_times2() +{ + boost::concurrent::sync_timed_queue<boost::executors::work> tq; + for(int i = 0; i < 10; i++) + { + steady_clock::duration d = milliseconds(i*100); + tq.push(func2, d); + } + while(!tq.empty()) + { + boost::executors::work fn = tq.pull(); + fn(); + } +} +#endif + +int main() +{ + test_all(); + test_all_with_try(); + test_deque_times(); + //test_deque_times2(); // rt fails + return boost::report_errors(); +} diff --git a/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp b/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp index 0d6d1025d..556ca68e9 100644 --- a/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp +++ b/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp @@ -15,7 +15,6 @@ #endif #define BOOST_THREAD_VERSION 4 -//#define BOOST_THREAD_QUEUE_DEPRECATE_OLD #include <boost/thread/sync_queue.hpp> #include <boost/thread/future.hpp> @@ -23,50 +22,13 @@ #include <boost/detail/lightweight_test.hpp> -#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD -struct call_push -{ - boost::sync_queue<int> *q_; - boost::barrier *go_; - - call_push(boost::sync_queue<int> *q, boost::barrier *go) : - q_(q), go_(go) - { - } - typedef void result_type; - void operator()() - { - go_->count_down_and_wait(); - q_->push(42); - - } -}; - -struct call_pull -{ - boost::sync_queue<int> *q_; - boost::barrier *go_; - - call_pull(boost::sync_queue<int> *q, boost::barrier *go) : - q_(q), go_(go) - { - } - typedef int result_type; - int operator()() - { - go_->count_down_and_wait(); - return q_->pull(); - } -}; -#endif - template <typename ValueType> -struct call_push_back +struct call_push { boost::sync_queue<ValueType> *q_; boost::barrier *go_; - call_push_back(boost::sync_queue<ValueType> *q, boost::barrier *go) : + call_push(boost::sync_queue<ValueType> *q, boost::barrier *go) : q_(q), go_(go) { } @@ -74,17 +36,17 @@ struct call_push_back void operator()() { go_->count_down_and_wait(); - q_->push_back(42); + q_->push(42); } }; template <typename ValueType> -struct call_pull_front +struct call_pull { boost::sync_queue<ValueType> *q_; boost::barrier *go_; - call_pull_front(boost::sync_queue<ValueType> *q, boost::barrier *go) : + call_pull(boost::sync_queue<ValueType> *q, boost::barrier *go) : q_(q), go_(go) { } @@ -92,17 +54,17 @@ struct call_pull_front ValueType operator()() { go_->count_down_and_wait(); - return q_->pull_front(); + return q_->pull(); } }; template <typename ValueType> -struct call_wait_pull_front +struct call_wait_pull { boost::sync_queue<ValueType> *q_; boost::barrier *go_; - call_wait_pull_front(boost::sync_queue<ValueType> *q, boost::barrier *go) : + call_wait_pull(boost::sync_queue<ValueType> *q, boost::barrier *go) : q_(q), go_(go) { } @@ -110,11 +72,10 @@ struct call_wait_pull_front boost::queue_op_status operator()(ValueType& v) { go_->wait(); - return q_->wait_pull_front(v); + return q_->wait_pull(v); } }; -#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD void test_concurrent_push_and_pull_on_empty_queue() { boost::sync_queue<int> q; @@ -127,127 +88,9 @@ void test_concurrent_push_and_pull_on_empty_queue() try { push_done=boost::async(boost::launch::async, -#if ! defined BOOST_NO_CXX11_LAMBDAS - [&q,&go]() - { - go.wait(); - q.push(42); - } -#else - call_push(&q,&go) -#endif - ); - pull_done=boost::async(boost::launch::async, -#if ! defined BOOST_NO_CXX11_LAMBDAS - [&q,&go]() -> int - { - go.wait(); - return q.pull(); - } -#else - call_pull(&q,&go) -#endif - ); - - push_done.get(); - BOOST_TEST_EQ(pull_done.get(), 42); - BOOST_TEST(q.empty()); - } - catch (...) - { - BOOST_TEST(false); - } -} - -void test_concurrent_push_on_empty_queue() -{ - boost::sync_queue<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, -#if ! defined BOOST_NO_CXX11_LAMBDAS - [&q,&go]() - { - go.wait(); - q.push(42); - } -#else - call_push(&q,&go) -#endif - ); - - for (unsigned int i = 0; i < n; ++i) - push_done[i].get(); - - BOOST_TEST(!q.empty()); - for (unsigned int i =0; i< n; ++i) - BOOST_TEST_EQ(q.pull(), 42); - BOOST_TEST(q.empty()); - - } - catch (...) - { - BOOST_TEST(false); - } -} - -void test_concurrent_pull_on_queue() -{ - boost::sync_queue<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(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(); - } -#else - call_pull(&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); - } -} -#endif - -void test_concurrent_push_back_and_pull_front_on_empty_queue() -{ - boost::sync_queue<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)); + call_push<int>(&q,&go)); pull_done=boost::async(boost::launch::async, - call_pull_front<int>(&q,&go)); + call_pull<int>(&q,&go)); push_done.get(); BOOST_TEST_EQ(pull_done.get(), 42); @@ -260,7 +103,7 @@ void test_concurrent_push_back_and_pull_front_on_empty_queue() } #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) -void test_concurrent_push_back_and_wait_pull_front_on_empty_queue() +void test_concurrent_push_and_wait_pull_on_empty_queue() { boost::sync_queue<int> q; const unsigned int n = 3; @@ -273,11 +116,11 @@ void test_concurrent_push_back_and_wait_pull_front_on_empty_queue() { for (unsigned int i =0; i< n; ++i) pull_done[i]=boost::async(boost::launch::async, - call_wait_pull_front<int>(&q,&go), + call_wait_pull<int>(&q,&go), boost::ref(results[i])); for (unsigned int i =0; i< n; ++i) - q.push_back(42); + q.push(42); for (unsigned int i = 0; i < n; ++i) { BOOST_TEST(pull_done[i].get() == boost::queue_op_status::success); @@ -291,7 +134,7 @@ void test_concurrent_push_back_and_wait_pull_front_on_empty_queue() } } -void test_concurrent_wait_pull_front_and_close_on_empty_queue() +void test_concurrent_wait_pull_and_close_on_empty_queue() { boost::sync_queue<int> q; const unsigned int n = 3; @@ -304,7 +147,7 @@ void test_concurrent_wait_pull_front_and_close_on_empty_queue() { for (unsigned int i =0; i< n; ++i) pull_done[i]=boost::async(boost::launch::async, - call_wait_pull_front<int>(&q,&go), + call_wait_pull<int>(&q,&go), boost::ref(results[i])); q.close(); @@ -321,7 +164,7 @@ void test_concurrent_wait_pull_front_and_close_on_empty_queue() } #endif -void test_concurrent_push_back_on_empty_queue() +void test_concurrent_push_on_empty_queue() { boost::sync_queue<int> q; const unsigned int n = 3; @@ -332,7 +175,7 @@ void test_concurrent_push_back_on_empty_queue() { for (unsigned int i =0; i< n; ++i) push_done[i]=boost::async(boost::launch::async, - call_push_back<int>(&q,&go)); + call_push<int>(&q,&go)); } catch (...) @@ -353,7 +196,7 @@ void test_concurrent_push_back_on_empty_queue() { BOOST_TEST(!q.empty()); for (unsigned int i =0; i< n; ++i) - BOOST_TEST_EQ(q.pull_front(), 42); + BOOST_TEST_EQ(q.pull(), 42); BOOST_TEST(q.empty()); } @@ -363,7 +206,7 @@ void test_concurrent_push_back_on_empty_queue() } } -void test_concurrent_pull_front_on_queue() +void test_concurrent_pull_on_queue() { boost::sync_queue<int> q; const unsigned int n = 3; @@ -374,7 +217,7 @@ void test_concurrent_pull_front_on_queue() try { for (unsigned int i =0; i< n; ++i) - q.push_back(42); + q.push(42); for (unsigned int i =0; i< n; ++i) pull_done[i]=boost::async(boost::launch::async, @@ -382,10 +225,10 @@ void test_concurrent_pull_front_on_queue() [&q,&go]() -> int { go.wait(); - return q.pull_front(); + return q.pull(); } #else - call_pull_front<int>(&q,&go) + call_pull<int>(&q,&go) #endif ); @@ -401,18 +244,13 @@ void test_concurrent_pull_front_on_queue() int main() { -#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD test_concurrent_push_and_pull_on_empty_queue(); - test_concurrent_push_on_empty_queue(); - test_concurrent_pull_on_queue(); -#endif - 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(); + test_concurrent_push_and_wait_pull_on_empty_queue(); + test_concurrent_wait_pull_and_close_on_empty_queue(); #endif - test_concurrent_push_back_on_empty_queue(); - test_concurrent_pull_front_on_queue(); + test_concurrent_push_on_empty_queue(); + test_concurrent_pull_on_queue(); return boost::report_errors(); } diff --git a/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp b/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp index 0d788d88c..8f47ec82a 100644 --- a/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp +++ b/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013 Vicente J. Botet Escriba +// Copyright (C) 2013,2015 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) @@ -10,7 +10,6 @@ // sync_queue(); #define BOOST_THREAD_VERSION 4 -//#define BOOST_THREAD_QUEUE_DEPRECATE_OLD #include <boost/thread/sync_queue.hpp> @@ -47,79 +46,8 @@ int main() BOOST_TEST_EQ(q.size(), 0u); BOOST_TEST(! q.closed()); } -#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD - { - // empty queue try_pull fails - boost::sync_queue<int> q; - int i; - BOOST_TEST(! q.try_pull(i)); - BOOST_TEST(q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 0u); - BOOST_TEST(! q.closed()); - } - { - // empty queue try_pull fails - boost::sync_queue<int> q; - BOOST_TEST(! q.try_pull()); - BOOST_TEST(q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 0u); - BOOST_TEST(! q.closed()); - } - { - // empty queue push rvalue/copyable succeeds - boost::sync_queue<int> q; - q.push(1); - BOOST_TEST(! q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 1u); - BOOST_TEST(! q.closed()); - } - { - // empty queue push lvalue/copyable succeeds - boost::sync_queue<int> q; - int i; - q.push(i); - BOOST_TEST(! q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 1u); - BOOST_TEST(! q.closed()); - } -#endif - - { - // empty queue try_pull fails - boost::sync_queue<int> q; - int i; - BOOST_TEST( boost::queue_op_status::empty == q.try_pull_front(i)); - BOOST_TEST(q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 0u); - BOOST_TEST(! q.closed()); - } - { - // empty queue push rvalue/copyable succeeds - boost::sync_queue<int> q; - q.push_back(1); - BOOST_TEST(! q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 1u); - BOOST_TEST(! q.closed()); - } - { - // empty queue push lvalue/copyable succeeds - boost::sync_queue<int> q; - int i; - q.push_back(i); - BOOST_TEST(! q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 1u); - BOOST_TEST(! q.closed()); - } -#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD -#if 0 +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES { // empty queue push rvalue/non_copyable succeeds boost::sync_queue<non_copyable> q; @@ -164,68 +92,7 @@ int main() { // empty queue try_push rvalue/copyable succeeds boost::sync_queue<int> q; - BOOST_TEST(q.try_push(1)); - BOOST_TEST(! q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 1u); - BOOST_TEST(! q.closed()); - } - { - // empty queue try_push rvalue/copyable succeeds - boost::sync_queue<int> q; - BOOST_TEST(q.try_push(1)); - BOOST_TEST(! q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 1u); - BOOST_TEST(! q.closed()); - } -#endif -#if 0 - { - // empty queue push rvalue/non_copyable succeeds - boost::sync_queue<non_copyable> q; - q.push_back(non_copyable(1)); - BOOST_TEST(! q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 1u); - BOOST_TEST(! q.closed()); - } -#endif - { - // empty queue push rvalue/non_copyable succeeds - boost::sync_queue<non_copyable> q; - non_copyable nc(1); - q.push_back(boost::move(nc)); - BOOST_TEST(! q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 1u); - BOOST_TEST(! q.closed()); - } - - { - // empty queue push rvalue succeeds - boost::sync_queue<int> q; - q.push_back(1); - q.push_back(2); - BOOST_TEST(! q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 2u); - BOOST_TEST(! q.closed()); - } - { - // empty queue push lvalue succeeds - boost::sync_queue<int> q; - int i; - q.push_back(i); - BOOST_TEST(! q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 1u); - BOOST_TEST(! q.closed()); - } - { - // empty queue try_push rvalue/copyable succeeds - boost::sync_queue<int> q; - BOOST_TEST(boost::queue_op_status::success == q.try_push_back(1)); + BOOST_TEST(boost::queue_op_status::success == q.try_push(1)); BOOST_TEST(! q.empty()); BOOST_TEST(! q.full()); BOOST_TEST_EQ(q.size(), 1u); @@ -234,60 +101,18 @@ int main() { // empty queue try_push rvalue/copyable succeeds boost::sync_queue<int> q; - BOOST_TEST(boost::queue_op_status::success == q.try_push_back(1)); - BOOST_TEST(! q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 1u); - BOOST_TEST(! q.closed()); - } -#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD -#if 0 - { - // empty queue try_push rvalue/non-copyable succeeds - boost::sync_queue<non_copyable> q; - BOOST_TEST(q.try_push(non_copyable())); - BOOST_TEST(! q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 1u); - BOOST_TEST(! q.closed()); - } -#endif - { - // empty queue try_push rvalue/non-copyable succeeds - boost::sync_queue<non_copyable> q; - non_copyable nc(1); - BOOST_TEST(q.try_push(boost::move(nc))); + BOOST_TEST(boost::queue_op_status::success == q.try_push(1)); BOOST_TEST(! q.empty()); BOOST_TEST(! q.full()); BOOST_TEST_EQ(q.size(), 1u); BOOST_TEST(! q.closed()); } - { - // empty queue try_push lvalue succeeds - boost::sync_queue<int> q; - int i=1; - BOOST_TEST(q.try_push(i)); - BOOST_TEST(! q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 1u); - BOOST_TEST(! q.closed()); - } - { - // empty queue try_push rvalue succeeds - boost::sync_queue<int> q; - BOOST_TEST(q.try_push(boost::no_block, 1)); - BOOST_TEST(! q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 1u); - BOOST_TEST(! q.closed()); - } -#endif -#if 0 +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES { // empty queue try_push rvalue/non-copyable succeeds boost::sync_queue<non_copyable> q; - BOOST_TEST(boost::queue_op_status::success ==q.try_push_back(non_copyable())); + BOOST_TEST(boost::queue_op_status::success ==q.try_push(non_copyable(1))); BOOST_TEST(! q.empty()); BOOST_TEST(! q.full()); BOOST_TEST_EQ(q.size(), 1u); @@ -298,7 +123,7 @@ int main() // empty queue try_push rvalue/non-copyable succeeds boost::sync_queue<non_copyable> q; non_copyable nc(1); - BOOST_TEST(boost::queue_op_status::success == q.try_push_back(boost::move(nc))); + BOOST_TEST(boost::queue_op_status::success == q.try_push(boost::move(nc))); BOOST_TEST(! q.empty()); BOOST_TEST(! q.full()); BOOST_TEST_EQ(q.size(), 1u); @@ -309,7 +134,7 @@ int main() // empty queue try_push lvalue succeeds boost::sync_queue<int> q; int i=1; - BOOST_TEST(boost::queue_op_status::success == q.try_push_back(i)); + BOOST_TEST(boost::queue_op_status::success == q.try_push(i)); BOOST_TEST(! q.empty()); BOOST_TEST(! q.full()); BOOST_TEST_EQ(q.size(), 1u); @@ -318,19 +143,18 @@ int main() { // empty queue try_push rvalue succeeds boost::sync_queue<int> q; - BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(1)); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(1)); BOOST_TEST(! q.empty()); BOOST_TEST(! q.full()); BOOST_TEST_EQ(q.size(), 1u); BOOST_TEST(! q.closed()); } -#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD -#if 0 +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES { - // empty queue try_push rvalue/non-copyable succeeds + // empty queue nonblocking_push rvalue/non-copyable succeeds boost::sync_queue<non_copyable> q; - BOOST_TEST(q.try_push(boost::no_block, non_copyable(1))); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(non_copyable(1))); BOOST_TEST(! q.empty()); BOOST_TEST(! q.full()); BOOST_TEST_EQ(q.size(), 1u); @@ -338,10 +162,10 @@ int main() } #endif { - // empty queue try_push rvalue/non-copyable succeeds + // empty queue nonblocking_push rvalue/non-copyable succeeds boost::sync_queue<non_copyable> q; non_copyable nc(1); - BOOST_TEST(q.try_push(boost::no_block, boost::move(nc))); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(boost::move(nc))); BOOST_TEST(! q.empty()); BOOST_TEST(! q.full()); BOOST_TEST_EQ(q.size(), 1u); @@ -400,7 +224,7 @@ int main() boost::sync_queue<int> q; q.push(1); int i; - BOOST_TEST(q.try_pull(i)); + BOOST_TEST(boost::queue_op_status::success == q.try_pull(i)); BOOST_TEST_EQ(i, 1); BOOST_TEST(q.empty()); BOOST_TEST(! q.full()); @@ -413,7 +237,7 @@ int main() non_copyable nc1(1); q.push(boost::move(nc1)); non_copyable nc(2); - BOOST_TEST(q.try_pull(nc)); + BOOST_TEST(boost::queue_op_status::success == q.try_pull(nc)); BOOST_TEST_EQ(nc, nc1); BOOST_TEST(q.empty()); BOOST_TEST(! q.full()); @@ -421,11 +245,11 @@ int main() BOOST_TEST(! q.closed()); } { - // 1-element queue try_pull succeed + // 1-element queue nonblocking_pull succeed boost::sync_queue<int> q; q.push(1); int i; - BOOST_TEST(q.try_pull(boost::no_block, i)); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(i)); BOOST_TEST_EQ(i, 1); BOOST_TEST(q.empty()); BOOST_TEST(! q.full()); @@ -433,177 +257,12 @@ int main() BOOST_TEST(! q.closed()); } { - // 1-element queue try_pull succeed + // 1-element queue nonblocking_pull succeed boost::sync_queue<non_copyable> q; non_copyable nc1(1); q.push(boost::move(nc1)); non_copyable nc(2); - BOOST_TEST(q.try_pull(boost::no_block, nc)); - BOOST_TEST_EQ(nc, nc1); - BOOST_TEST(q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 0u); - BOOST_TEST(! q.closed()); - } - { - // 1-element queue try_pull succeed - boost::sync_queue<int> q; - q.push(1); - boost::shared_ptr<int> i = q.try_pull(); - BOOST_TEST_EQ(*i, 1); - BOOST_TEST(q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 0u); - BOOST_TEST(! q.closed()); - } - - { - // closed invariants - boost::sync_queue<int> q; - q.close(); - BOOST_TEST(q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 0u); - BOOST_TEST(q.closed()); - } - { - // closed queue push fails - boost::sync_queue<int> q; - q.close(); - try { - q.push(1); - BOOST_TEST(false); - } catch (...) { - BOOST_TEST(q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 0u); - BOOST_TEST(q.closed()); - } - } - { - // closed empty queue try_pull_front closed - boost::sync_queue<int> q; - q.close(); - int i; - BOOST_TEST(boost::queue_op_status::closed == q.try_pull_front(i)); - BOOST_TEST(q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 0u); - BOOST_TEST(q.closed()); - } - { - // closed empty queue nonblocking_pull_front closed - boost::sync_queue<int> q; - q.close(); - int i; - BOOST_TEST(boost::queue_op_status::closed == q.nonblocking_pull_front(i)); - BOOST_TEST(q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 0u); - BOOST_TEST(q.closed()); - } - { - // 1-element closed queue pull succeed - boost::sync_queue<int> q; - q.push(1); - q.close(); - int i; - q.pull(i); - BOOST_TEST_EQ(i, 1); - BOOST_TEST(q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 0u); - BOOST_TEST(q.closed()); - } -#endif -#if 0 - { - // empty queue nonblocking_push_back rvalue/non-copyable succeeds - boost::sync_queue<non_copyable> q; - BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(non_copyable(1))); - BOOST_TEST(! q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 1u); - BOOST_TEST(! q.closed()); - } -#endif - { - // empty queue nonblocking_push_back rvalue/non-copyable succeeds - boost::sync_queue<non_copyable> q; - non_copyable nc(1); - BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(boost::move(nc))); - BOOST_TEST(! q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 1u); - BOOST_TEST(! q.closed()); - } - { - // 1-element queue pull_front succeed - boost::sync_queue<int> q; - q.push_back(1); - int i; - q.pull_front(i); - BOOST_TEST_EQ(i, 1); - BOOST_TEST(q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 0u); - BOOST_TEST(! q.closed()); - } - { - // 1-element queue pull_front succeed - boost::sync_queue<non_copyable> q; - non_copyable nc1(1); - q.push_back(boost::move(nc1)); - non_copyable nc2(2); - q.pull_front(nc2); - BOOST_TEST_EQ(nc1, nc2); - BOOST_TEST(q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 0u); - BOOST_TEST(! q.closed()); - } - { - // 1-element queue pull_front succeed - boost::sync_queue<int> q; - q.push_back(1); - int i = q.pull_front(); - BOOST_TEST_EQ(i, 1); - BOOST_TEST(q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 0u); - BOOST_TEST(! q.closed()); - } - { - // 1-element queue pull_front succeed - boost::sync_queue<non_copyable> q; - non_copyable nc1(1); - q.push_back(boost::move(nc1)); - non_copyable nc = q.pull_front(); - BOOST_TEST_EQ(nc, nc1); - BOOST_TEST(q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 0u); - BOOST_TEST(! q.closed()); - } - { - // 1-element queue try_pull_front succeed - boost::sync_queue<int> q; - q.push_back(1); - int i; - BOOST_TEST(boost::queue_op_status::success == q.try_pull_front(i)); - BOOST_TEST_EQ(i, 1); - BOOST_TEST(q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 0u); - BOOST_TEST(! q.closed()); - } - { - // 1-element queue try_pull_front succeed - boost::sync_queue<non_copyable> q; - non_copyable nc1(1); - q.push_back(boost::move(nc1)); - non_copyable nc(2); - BOOST_TEST(boost::queue_op_status::success == q.try_pull_front(nc)); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(nc)); BOOST_TEST_EQ(nc, nc1); BOOST_TEST(q.empty()); BOOST_TEST(! q.full()); @@ -611,37 +270,12 @@ int main() BOOST_TEST(! q.closed()); } { - // 1-element queue nonblocking_pull_front succeed - boost::sync_queue<int> q; - q.push_back(1); - int i; - BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull_front(i)); - BOOST_TEST_EQ(i, 1); - BOOST_TEST(q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 0u); - BOOST_TEST(! q.closed()); - } - { - // 1-element queue nonblocking_pull_front succeed + // 1-element queue wait_pull succeed boost::sync_queue<non_copyable> q; non_copyable nc1(1); - q.push_back(boost::move(nc1)); - non_copyable nc(2); - BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull_front(nc)); - BOOST_TEST_EQ(nc, nc1); - BOOST_TEST(q.empty()); - BOOST_TEST(! q.full()); - BOOST_TEST_EQ(q.size(), 0u); - BOOST_TEST(! q.closed()); - } - { - // 1-element queue wait_pull_front succeed - boost::sync_queue<non_copyable> q; - non_copyable nc1(1); - q.push_back(boost::move(nc1)); + q.push(boost::move(nc1)); non_copyable nc(2); - BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(nc)); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc)); BOOST_TEST_EQ(nc, nc1); BOOST_TEST(q.empty()); BOOST_TEST(! q.full()); @@ -649,11 +283,11 @@ int main() BOOST_TEST(! q.closed()); } { - // 1-element queue wait_pull_front succeed + // 1-element queue wait_pull succeed boost::sync_queue<int> q; - q.push_back(1); + q.push(1); int i; - BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(i)); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i)); BOOST_TEST_EQ(i, 1); BOOST_TEST(q.empty()); BOOST_TEST(! q.full()); @@ -661,12 +295,12 @@ int main() BOOST_TEST(! q.closed()); } { - // 1-element queue wait_pull_front succeed + // 1-element queue wait_pull succeed boost::sync_queue<non_copyable> q; non_copyable nc1(1); - q.push_back(boost::move(nc1)); + q.push(boost::move(nc1)); non_copyable nc(2); - BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(nc)); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc)); BOOST_TEST_EQ(nc, nc1); BOOST_TEST(q.empty()); BOOST_TEST(! q.full()); @@ -688,7 +322,7 @@ int main() boost::sync_queue<int> q; q.close(); try { - q.push_back(1); + q.push(1); BOOST_TEST(false); } catch (...) { BOOST_TEST(q.empty()); @@ -700,10 +334,10 @@ int main() { // 1-element closed queue pull succeed boost::sync_queue<int> q; - q.push_back(1); + q.push(1); q.close(); int i; - q.pull_front(i); + q.pull(i); BOOST_TEST_EQ(i, 1); BOOST_TEST(q.empty()); BOOST_TEST(! q.full()); @@ -711,12 +345,12 @@ int main() BOOST_TEST(q.closed()); } { - // 1-element closed queue wait_pull_front succeed + // 1-element closed queue wait_pull succeed boost::sync_queue<int> q; - q.push_back(1); + q.push(1); q.close(); int i; - BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(i)); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i)); BOOST_TEST_EQ(i, 1); BOOST_TEST(q.empty()); BOOST_TEST(! q.full()); @@ -724,13 +358,13 @@ int main() BOOST_TEST(q.closed()); } { - // closed empty queue wait_pull_front fails + // closed empty queue wait_pull fails boost::sync_queue<int> q; q.close(); BOOST_TEST(q.empty()); BOOST_TEST(q.closed()); int i; - BOOST_TEST(boost::queue_op_status::closed == q.wait_pull_front(i)); + BOOST_TEST(boost::queue_op_status::closed == q.wait_pull(i)); BOOST_TEST(q.empty()); BOOST_TEST(q.closed()); } diff --git a/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_bind.cpp b/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_bind.cpp index 58ec01ab4..2da08c2f4 100644 --- a/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_bind.cpp +++ b/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_bind.cpp @@ -72,7 +72,7 @@ void test_bind() { BOOST_TEST(c == 345); } -#if defined(BOOST_NO_VARIADIC_TEMPLATES) +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) void test_bind_non_const() { std::cout << "c++11 variadic templates disabled" << std::endl; } |