|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r84888 - in trunk: boost/thread libs/thread/test libs/thread/test/sync/mutual_exclusion/sync_bounded_queue libs/thread/test/sync/mutual_exclusion/sync_queue
From: vicente.botet_at_[hidden]
Date: 2013-06-23 16:47:03
Author: viboes
Date: 2013-06-23 16:47:03 EDT (Sun, 23 Jun 2013)
New Revision: 84888
URL: http://svn.boost.org/trac/boost/changeset/84888
Log:
Thread: fix some issues with sync_bounded_queue and added tests.
Added:
trunk/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/
trunk/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp (contents, props changed)
trunk/libs/thread/test/sync/mutual_exclusion/sync_queue/
trunk/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp (contents, props changed)
trunk/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp (contents, props changed)
Text files modified:
trunk/boost/thread/sync_bounded_queue.hpp | 96 +++++++++-------
trunk/boost/thread/sync_queue.hpp | 79 ++++++-------
trunk/libs/thread/test/Jamfile.v2 | 11 +
trunk/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp | 226 ++++++++++++++++++++++++++++++++++++++++
trunk/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp | 213 +++++++++++++++++++++++++++++++++++++
trunk/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp | 203 +++++++++++++++++++++++++++++++++++
6 files changed, 742 insertions(+), 86 deletions(-)
Modified: trunk/boost/thread/sync_bounded_queue.hpp
==============================================================================
--- trunk/boost/thread/sync_bounded_queue.hpp Sun Jun 23 16:45:26 2013 (r84887)
+++ trunk/boost/thread/sync_bounded_queue.hpp 2013-06-23 16:47:03 EDT (Sun, 23 Jun 2013) (r84888)
@@ -48,31 +48,31 @@
~sync_bounded_queue();
// Observers
- bool empty() const;
- bool full() const;
- size_type capacity() const;
- size_type size() const;
- bool closed() const;
+ inline bool empty() const;
+ inline bool full() const;
+ inline size_type capacity() const;
+ inline size_type size() const;
+ inline bool closed() const;
// Modifiers
- void close();
+ inline void close();
- void push(const value_type& x);
- void push(BOOST_THREAD_RV_REF(value_type) x);
- bool try_push(const value_type& x);
- bool try_push(BOOST_THREAD_RV_REF(value_type) x);
- bool try_push(no_block_tag, const value_type& x);
- bool try_push(no_block_tag, BOOST_THREAD_RV_REF(value_type) x);
+ inline void push(const value_type& x);
+ inline void push(BOOST_THREAD_RV_REF(value_type) x);
+ inline bool try_push(const value_type& x);
+ inline bool try_push(BOOST_THREAD_RV_REF(value_type) x);
+ inline bool try_push(no_block_tag, const value_type& x);
+ inline bool try_push(no_block_tag, BOOST_THREAD_RV_REF(value_type) x);
// Observers/Modifiers
- void pull(value_type&);
- void pull(ValueType& elem, bool & closed);
+ inline void pull(value_type&);
+ inline void pull(ValueType& elem, bool & closed);
// enable_if is_nothrow_copy_movable<value_type>
- value_type pull();
- shared_ptr<ValueType> ptr_pull();
- bool try_pull(value_type&);
- bool try_pull(no_block_tag,value_type&);
- shared_ptr<ValueType> try_pull();
+ inline value_type pull();
+ inline shared_ptr<ValueType> ptr_pull();
+ inline bool try_pull(value_type&);
+ inline bool try_pull(no_block_tag,value_type&);
+ inline shared_ptr<ValueType> try_pull();
private:
mutable mutex mtx_;
@@ -86,42 +86,51 @@
size_type capacity_;
bool closed_;
- size_type inc(size_type idx) const BOOST_NOEXCEPT
+ inline size_type inc(size_type idx) const BOOST_NOEXCEPT
{
return (idx + 1) % capacity_;
}
- bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
+ inline bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
{
return in_ == out_;
}
- bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ inline bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
{
return in_ == out_;
}
- size_type capacity(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ inline bool full(unique_lock<mutex>& ) const BOOST_NOEXCEPT
{
- return capacity;
+ return (inc(in_) == out_);
}
- size_type size(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ inline bool full(lock_guard<mutex>& ) const BOOST_NOEXCEPT
{
- return ((out_+capacity_-in_) % capacity_)-1;
+ return (inc(in_) == out_);
+ }
+ inline size_type capacity(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ {
+ return capacity_-1;
+ }
+ inline size_type size(lock_guard<mutex>& lk) const BOOST_NOEXCEPT
+ {
+ if (full(lk)) return capacity(lk);
+ return ((out_+capacity(lk)-in_) % capacity(lk));
}
- void throw_if_closed(unique_lock<mutex>&);
+ inline void throw_if_closed(unique_lock<mutex>&);
- bool try_pull(value_type& x, unique_lock<mutex>& lk);
- bool try_push(const value_type& x, unique_lock<mutex>& lk);
- bool try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
- shared_ptr<value_type> try_pull(unique_lock<mutex>& lk);
+ inline bool try_pull(value_type& x, unique_lock<mutex>& lk);
+ inline bool try_push(const value_type& x, unique_lock<mutex>& lk);
+ inline bool try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
+ inline shared_ptr<value_type> try_pull(unique_lock<mutex>& lk);
- void wait_until_not_empty(unique_lock<mutex>& lk);
- void wait_until_not_empty(unique_lock<mutex>& lk, bool&);
- size_type wait_until_not_full(unique_lock<mutex>& lk);
- size_type wait_until_not_full(unique_lock<mutex>& lk, bool&);
+ inline void wait_until_not_empty(unique_lock<mutex>& lk);
+ inline void wait_until_not_empty(unique_lock<mutex>& lk, bool&);
+ inline size_type wait_until_not_full(unique_lock<mutex>& lk);
+ inline size_type wait_until_not_full(unique_lock<mutex>& lk, bool&);
- void notify_not_empty_if_needed(unique_lock<mutex>& lk)
+ inline void notify_not_empty_if_needed(unique_lock<mutex>& lk)
{
if (waiting_empty_ > 0)
{
@@ -130,7 +139,7 @@
not_empty_.notify_one();
}
}
- void notify_not_full_if_needed(unique_lock<mutex>& lk)
+ inline void notify_not_full_if_needed(unique_lock<mutex>& lk)
{
if (waiting_full_ > 0)
{
@@ -140,13 +149,13 @@
}
}
- void pull(value_type& elem, unique_lock<mutex>& lk)
+ inline void pull(value_type& elem, unique_lock<mutex>& lk)
{
elem = boost::move(data_[out_]);
out_ = inc(out_);
notify_not_full_if_needed(lk);
}
- boost::shared_ptr<value_type> ptr_pull(unique_lock<mutex>& lk)
+ inline boost::shared_ptr<value_type> ptr_pull(unique_lock<mutex>& lk)
{
shared_ptr<value_type> res = make_shared<value_type>(boost::move(data_[out_]));
out_ = inc(out_);
@@ -154,26 +163,23 @@
return res;
}
-
- void set_in(size_type in, unique_lock<mutex>& lk)
+ inline void set_in(size_type in, unique_lock<mutex>& lk)
{
in_ = in;
notify_not_empty_if_needed(lk);
}
- void push_at(const value_type& elem, size_type in_p_1, unique_lock<mutex>& lk)
+ inline void push_at(const value_type& elem, size_type in_p_1, unique_lock<mutex>& lk)
{
data_[in_] = elem;
set_in(in_p_1, lk);
}
- void push_at(BOOST_THREAD_RV_REF(value_type) elem, size_type in_p_1, unique_lock<mutex>& lk)
+ inline void push_at(BOOST_THREAD_RV_REF(value_type) elem, size_type in_p_1, unique_lock<mutex>& lk)
{
data_[in_] = boost::move(elem);
set_in(in_p_1, lk);
}
-
-
};
template <typename ValueType>
Modified: trunk/boost/thread/sync_queue.hpp
==============================================================================
--- trunk/boost/thread/sync_queue.hpp Sun Jun 23 16:45:26 2013 (r84887)
+++ trunk/boost/thread/sync_queue.hpp 2013-06-23 16:47:03 EDT (Sun, 23 Jun 2013) (r84888)
@@ -37,37 +37,36 @@
// Constructors/Assignment/Destructors
BOOST_THREAD_NO_COPYABLE(sync_queue)
- sync_queue();
- template <typename Range>
- explicit sync_queue(Range range);
- ~sync_queue();
+ inline sync_queue();
+ //template <typename Range>
+ //inline explicit sync_queue(Range range);
+ inline ~sync_queue();
// Observers
- bool empty() const;
- bool full() const;
- size_type size() const;
- bool closed() const;
+ inline bool empty() const;
+ inline bool full() const;
+ inline size_type size() const;
+ inline bool closed() const;
// Modifiers
- void close();
+ inline void close();
- void push(const value_type& x);
- void push(BOOST_THREAD_RV_REF(value_type) x);
- bool try_push(const value_type& x);
- bool try_push(BOOST_THREAD_RV_REF(value_type) x);
- bool try_push(no_block_tag, const value_type& x);
- bool try_push(no_block_tag, BOOST_THREAD_RV_REF(value_type) x);
+ inline void push(const value_type& x);
+ inline void push(BOOST_THREAD_RV_REF(value_type) x);
+ inline bool try_push(const value_type& x);
+ inline bool try_push(BOOST_THREAD_RV_REF(value_type) x);
+ inline bool try_push(no_block_tag, const value_type& x);
+ inline bool try_push(no_block_tag, BOOST_THREAD_RV_REF(value_type) x);
// Observers/Modifiers
- void pull(value_type&);
- void pull(ValueType& elem, bool & closed);
+ inline void pull(value_type&);
+ inline void pull(ValueType& elem, bool & closed);
// enable_if is_nothrow_copy_movable<value_type>
- value_type pull();
- shared_ptr<ValueType> ptr_pull();
- bool try_pull(value_type&);
- bool try_pull(no_block_tag,value_type&);
- shared_ptr<ValueType> try_pull();
-
+ inline value_type pull();
+ inline shared_ptr<ValueType> ptr_pull();
+ inline bool try_pull(value_type&);
+ inline bool try_pull(no_block_tag,value_type&);
+ inline shared_ptr<ValueType> try_pull();
private:
mutable mutex mtx_;
@@ -76,32 +75,31 @@
boost::container::deque<ValueType> data_;
bool closed_;
- bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
+ inline bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
{
return data_.empty();
}
- bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ inline bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
{
return data_.empty();
}
- size_type size(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ inline size_type size(lock_guard<mutex>& ) const BOOST_NOEXCEPT
{
return data_.size();
}
- void throw_if_closed(unique_lock<mutex>&);
-
- bool try_pull(value_type& x, unique_lock<mutex>& lk);
- bool try_push(const value_type& x, unique_lock<mutex>& lk);
- bool try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
- shared_ptr<value_type> try_pull(unique_lock<mutex>& lk);
+ inline void throw_if_closed(unique_lock<mutex>&);
- void wait_until_not_empty(unique_lock<mutex>& lk);
- void wait_until_not_empty(unique_lock<mutex>& lk, bool&);
+ inline bool try_pull(value_type& x, unique_lock<mutex>& lk);
+ inline bool try_push(const value_type& x, unique_lock<mutex>& lk);
+ inline bool try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
+ inline shared_ptr<value_type> try_pull(unique_lock<mutex>& lk);
+ inline void wait_until_not_empty(unique_lock<mutex>& lk);
+ inline void wait_until_not_empty(unique_lock<mutex>& lk, bool&);
- void notify_not_empty_if_needed(unique_lock<mutex>& lk)
+ inline void notify_not_empty_if_needed(unique_lock<mutex>& lk)
{
if (waiting_empty_ > 0)
{
@@ -111,31 +109,29 @@
}
}
- void pull(value_type& elem, unique_lock<mutex>& )
+ inline void pull(value_type& elem, unique_lock<mutex>& )
{
elem = boost::move(data_.front());
data_.pop_front();
}
- boost::shared_ptr<value_type> ptr_pull(unique_lock<mutex>& )
+ inline boost::shared_ptr<value_type> ptr_pull(unique_lock<mutex>& )
{
shared_ptr<value_type> res = make_shared<value_type>(boost::move(data_.front()));
data_.pop_front();
return res;
}
- void push(const value_type& elem, unique_lock<mutex>& lk)
+ inline void push(const value_type& elem, unique_lock<mutex>& lk)
{
data_.push_back(elem);
notify_not_empty_if_needed(lk);
}
- void push(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk)
+ inline void push(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk)
{
data_.push(boost::move(elem));
notify_not_empty_if_needed(lk);
}
-
-
};
template <typename ValueType>
@@ -309,6 +305,7 @@
++waiting_empty_;
not_empty_.wait(lk);
}
+ closed=false;
}
template <typename ValueType>
Modified: trunk/libs/thread/test/Jamfile.v2
==============================================================================
--- trunk/libs/thread/test/Jamfile.v2 Sun Jun 23 16:45:26 2013 (r84887)
+++ trunk/libs/thread/test/Jamfile.v2 2013-06-23 16:47:03 EDT (Sun, 23 Jun 2013) (r84888)
@@ -630,6 +630,15 @@
[ thread-run2-noit ./sync/mutual_exclusion/null_mutex/try_lock_until_pass.cpp : null_mutex__try_lock_until_p ]
;
+ test-suite ts_sync_queue
+ :
+ [ thread-run2-noit ./sync/mutual_exclusion/sync_queue/single_thread_pass.cpp : sync_queue__single_thread_p ]
+ ;
+
+ test-suite ts_sync_bounded_queue
+ :
+ [ thread-run2-noit ./sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp : sync_bounded_queue__single_thread_p ]
+ ;
#explicit ts_this_thread ;
test-suite ts_this_thread
@@ -779,6 +788,8 @@
#[ thread-run test_8586.cpp ]
#[ thread-run test_8596.cpp ]
#[ thread-run test_8600.cpp ]
+ #[ thread-run2-noit ./sync/mutual_exclusion/sync_bounded_queue/multi_thread_pass.cpp : sync_bounded_queue__multi_thread_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp : sync_queue__multi_thread_p ]
;
Added: trunk/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp 2013-06-23 16:47:03 EDT (Sun, 23 Jun 2013) (r84888)
@@ -0,0 +1,226 @@
+// 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/sync_bounded_queue.hpp>
+
+// class sync_bounded_queue<T>
+
+// sync_bounded_queue();
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/sync_bounded_queue.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ // default queue invariants
+ boost::sync_bounded_queue<int> q(2);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST_EQ(q.capacity(), 2);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_pull fails
+ boost::sync_bounded_queue<int> q(2);
+ int i;
+ BOOST_TEST(! q.try_pull(i));
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_pull fails
+ boost::sync_bounded_queue<int> q(2);
+ BOOST_TEST(! q.try_pull());
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push rvalue succeeds
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push rvalue succeeds
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ q.push(2);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST( q.full());
+ BOOST_TEST_EQ(q.size(), 2);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push value succeeds
+ boost::sync_bounded_queue<int> q(2);
+ int i;
+ q.push(i);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue succeeds
+ boost::sync_bounded_queue<int> q(2);
+ BOOST_TEST(q.try_push(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push value succeeds
+ boost::sync_bounded_queue<int> q(2);
+ int i;
+ BOOST_TEST(q.try_push(i));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue succeeds
+ boost::sync_bounded_queue<int> q(2);
+ BOOST_TEST(q.try_push(boost::no_block, 1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ int i;
+ q.pull(i);
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ 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(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ int i;
+ BOOST_TEST(q.try_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ int i;
+ BOOST_TEST(q.try_pull(boost::no_block, i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ 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(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // full queue try_push rvalue fails
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ q.push(2);
+ BOOST_TEST(! q.try_push(3));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST( q.full());
+ BOOST_TEST_EQ(q.size(), 2);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // full queue try_push succeeds
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ q.push(2);
+ BOOST_TEST(q.try_pull());
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+
+ {
+ // closed invariants
+ boost::sync_bounded_queue<int> q(2);
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed queue push fails
+ boost::sync_bounded_queue<int> q(2);
+ q.close();
+ try {
+ q.push(1);
+ BOOST_TEST(false);
+ } catch (...) {
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(q.closed());
+ }
+ }
+ {
+ // 1-element closed queue pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ 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(), 0);
+ BOOST_TEST(q.closed());
+ }
+
+ return boost::report_errors();
+}
+
Added: trunk/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp 2013-06-23 16:47:03 EDT (Sun, 23 Jun 2013) (r84888)
@@ -0,0 +1,213 @@
+// 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/sync_queue.hpp>
+
+// class sync_queue<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/sync_queue.hpp>
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/future.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+struct call_push
+{
+ boost::sync_queue<int> &q_;
+ boost::shared_future<void> ready_;
+ boost::promise<void> &op_ready_;
+
+ call_push(boost::sync_queue<int> &q, boost::shared_future<void> ready, boost::promise<void> &op_ready) :
+ q_(q), ready_(ready), op_ready_(op_ready)
+ {
+ }
+ typedef void result_type;
+ void operator()()
+ {
+ op_ready_.set_value();
+ ready_.wait();
+ q_.push(42);
+ }
+
+};
+
+struct call_pull
+{
+ boost::sync_queue<int> &q_;
+ boost::shared_future<void> ready_;
+ boost::promise<void> &op_ready_;
+
+ call_pull(boost::sync_queue<int> &q, boost::shared_future<void> ready, boost::promise<void> &op_ready) :
+ q_(q), ready_(ready), op_ready_(op_ready)
+ {
+ }
+ typedef int result_type;
+ int operator()()
+ {
+ op_ready_.set_value();
+ ready_.wait();
+ return q_.pull();
+ }
+
+};
+
+void test_concurrent_push_and_pull_on_empty_queue()
+{
+ boost::sync_queue<int> q;
+
+ boost::promise<void> go, push_ready, pull_ready;
+ boost::shared_future<void> ready(go.get_future());
+
+ boost::future<void> push_done;
+ boost::future<int> pull_done;
+
+ try
+ {
+ push_done=boost::async(boost::launch::async,
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+ [&q,ready,&push_ready]()
+ {
+ push_ready.set_value();
+ ready.wait();
+ q.push(42);
+ }
+#else
+ call_push(q,ready,push_ready)
+#endif
+ );
+ pull_done=boost::async(boost::launch::async,
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+ [&q,ready,&pull_ready]()
+ {
+ pull_ready.set_value();
+ ready.wait();
+ return q.pull();
+ }
+#else
+ call_pull(q,ready,pull_ready)
+#endif
+ );
+ push_ready.get_future().wait();
+ pull_ready.get_future().wait();
+ go.set_value();
+
+ push_done.get();
+ BOOST_TEST_EQ(pull_done.get(), 42);
+ BOOST_TEST(q.empty());
+ }
+ catch (...)
+ {
+ go.set_value();
+ BOOST_TEST(false);
+ }
+}
+
+void test_concurrent_push_on_empty_queue()
+{
+ boost::sync_queue<int> q;
+ const unsigned int n = 3;
+ boost::promise<void> go;
+ boost::shared_future<void> ready(go.get_future());
+
+ boost::promise<void> push_ready[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,ready,&push_ready,i]()
+ {
+ push_ready[i].set_value();
+ ready.wait();
+ q.push(42);
+ }
+#else
+ call_push(q,ready,push_ready[i])
+#endif
+ );
+
+ for (unsigned int i = 0; i < n; ++i)
+ push_ready[i].get_future().wait();
+ go.set_value();
+
+ 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 (...)
+ {
+ go.set_value();
+ BOOST_TEST(false);
+ }
+}
+
+void test_concurrent_pull_on_queue()
+{
+ boost::sync_queue<int> q;
+ const unsigned int n = 3;
+ boost::promise<void> go;
+ boost::shared_future<void> ready(go.get_future());
+
+ boost::promise<void> pull_ready[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,ready,&pull_ready,i]()
+ {
+ pull_ready[i].set_value();
+ ready.wait();
+ return q.pull();
+ }
+#else
+ call_pull(q,ready,pull_ready[i])
+#endif
+ );
+
+ for (unsigned int i = 0; i < n; ++i)
+ pull_ready[i].get_future().wait();
+ go.set_value();
+
+ for (unsigned int i = 0; i < n; ++i)
+ BOOST_TEST_EQ(pull_done[i].get(), 42);
+ BOOST_TEST(q.empty());
+ }
+ catch (...)
+ {
+ go.set_value();
+ BOOST_TEST(false);
+ }
+}
+
+int main()
+{
+ test_concurrent_push_and_pull_on_empty_queue();
+ test_concurrent_push_on_empty_queue();
+ test_concurrent_pull_on_queue();
+
+ return boost::report_errors();
+}
+
Added: trunk/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp 2013-06-23 16:47:03 EDT (Sun, 23 Jun 2013) (r84888)
@@ -0,0 +1,203 @@
+// 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/sync_queue.hpp>
+
+// class sync_queue<T>
+
+// sync_queue();
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/sync_queue.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ // default queue invariants
+ boost::sync_queue<int> q;
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 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(), 0);
+ 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(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push rvalue succeeds
+ boost::sync_queue<int> q;
+ q.push(1);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push rvalue succeeds
+ boost::sync_queue<int> q;
+ q.push(1);
+ q.push(2);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 2);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push value succeeds
+ boost::sync_queue<int> q;
+ int i;
+ q.push(i);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue 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(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push value succeeds
+ boost::sync_queue<int> q;
+ int i;
+ BOOST_TEST(q.try_push(i));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ 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(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull succeed
+ boost::sync_queue<int> q;
+ q.push(1);
+ int i;
+ q.pull(i);
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull succeed
+ boost::sync_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(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull succeed
+ boost::sync_queue<int> q;
+ q.push(1);
+ int i;
+ BOOST_TEST(q.try_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull succeed
+ boost::sync_queue<int> q;
+ q.push(1);
+ int i;
+ BOOST_TEST(q.try_pull(boost::no_block, i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ 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(), 0);
+ 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(), 0);
+ 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(), 0);
+ 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(), 0);
+ BOOST_TEST(q.closed());
+ }
+
+ return boost::report_errors();
+}
+
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk