Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r83540 - in branches/release: boost/lockfree boost/lockfree/detail libs/lockfree libs/lockfree/test
From: tim_at_[hidden]
Date: 2013-03-24 09:08:35


Author: timblechmann
Date: 2013-03-24 09:08:34 EDT (Sun, 24 Mar 2013)
New Revision: 83540
URL: http://svn.boost.org/trac/boost/changeset/83540

Log:
lockfree: merge changes from trunk

Added:
   branches/release/libs/lockfree/test/spsc_queue_stress_test.cpp
      - copied unchanged from r83537, /trunk/libs/lockfree/test/spsc_queue_stress_test.cpp
Properties modified:
   branches/release/boost/lockfree/ (props changed)
   branches/release/libs/lockfree/ (props changed)
Text files modified:
   branches/release/boost/lockfree/detail/freelist.hpp | 5
   branches/release/boost/lockfree/queue.hpp | 80 ++++++++++++
   branches/release/boost/lockfree/spsc_queue.hpp | 74 +++++++++++
   branches/release/boost/lockfree/stack.hpp | 76 +++++++++++
   branches/release/libs/lockfree/test/queue_test.cpp | 54 ++++++++
   branches/release/libs/lockfree/test/spsc_queue_test.cpp | 244 ++++++++-------------------------------
   branches/release/libs/lockfree/test/stack_test.cpp | 53 ++++++++
   branches/release/libs/lockfree/test/test_helpers.hpp | 22 +++
   8 files changed, 406 insertions(+), 202 deletions(-)

Modified: branches/release/boost/lockfree/detail/freelist.hpp
==============================================================================
--- branches/release/boost/lockfree/detail/freelist.hpp (original)
+++ branches/release/boost/lockfree/detail/freelist.hpp 2013-03-24 09:08:34 EDT (Sun, 24 Mar 2013)
@@ -298,6 +298,11 @@
         return (index == rhs.index) && (tag == rhs.tag);
     }
 
+ bool operator!=(tagged_index const & rhs) const
+ {
+ return !operator==(rhs);
+ }
+
 protected:
     index_t index;
     tag_t tag;

Modified: branches/release/boost/lockfree/queue.hpp
==============================================================================
--- branches/release/boost/lockfree/queue.hpp (original)
+++ branches/release/boost/lockfree/queue.hpp 2013-03-24 09:08:34 EDT (Sun, 24 Mar 2013)
@@ -2,7 +2,7 @@
 // Michael, M. M. and Scott, M. L.,
 // "simple, fast and practical non-blocking and blocking concurrent queue algorithms"
 //
-// Copyright (C) 2008, 2009, 2010, 2011 Tim Blechmann
+// Copyright (C) 2008-2013 Tim Blechmann
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
@@ -11,10 +11,10 @@
 #ifndef BOOST_LOCKFREE_FIFO_HPP_INCLUDED
 #define BOOST_LOCKFREE_FIFO_HPP_INCLUDED
 
-#include <memory> /* std::auto_ptr */
-
 #include <boost/assert.hpp>
+#ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS
 #include <boost/noncopyable.hpp>
+#endif
 #include <boost/static_assert.hpp>
 #include <boost/type_traits/has_trivial_assign.hpp>
 #include <boost/type_traits/has_trivial_destructor.hpp>
@@ -69,8 +69,10 @@
 #else
 template <typename T, ...Options>
 #endif
-class queue:
- boost::noncopyable
+class queue
+#ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS
+ : boost::noncopyable
+#endif
 {
 private:
 #ifndef BOOST_DOXYGEN_INVOKED
@@ -86,7 +88,7 @@
     typedef typename detail::queue_signature::bind<A0, A1, A2>::type bound_args;
 
     static const bool has_capacity = detail::extract_capacity<bound_args>::has_capacity;
- static const size_t capacity = detail::extract_capacity<bound_args>::capacity;
+ static const size_t capacity = detail::extract_capacity<bound_args>::capacity + 1; // the queue uses one dummy node
     static const bool fixed_sized = detail::extract_fixed_sized<bound_args>::value;
     static const bool node_based = !(has_capacity || fixed_sized);
     static const bool compile_time_sized = has_capacity;
@@ -137,6 +139,12 @@
 
 #endif
 
+#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS
+ queue(queue const &) = delete;
+ queue(queue &&) = delete;
+ const queue& operator=( const queue& ) = delete;
+#endif
+
 public:
     typedef T value_type;
     typedef typename implementation_defined::allocator allocator;
@@ -458,6 +466,66 @@
         }
     }
 
+ /** consumes one element via a functor
+ *
+ * pops one element from the queue and applies the functor on this object
+ *
+ * \returns true, if one element was consumed
+ *
+ * \note Thread-safe and non-blocking, if functor is thread-safe and non-blocking
+ * */
+ template <typename Functor>
+ bool consume_one(Functor & f)
+ {
+ T element;
+ bool success = pop(element);
+ if (success)
+ f(element);
+
+ return success;
+ }
+
+ /// \copydoc boost::lockfree::queue::consume_one(Functor & rhs)
+ template <typename Functor>
+ bool consume_one(Functor const & f)
+ {
+ T element;
+ bool success = pop(element);
+ if (success)
+ f(element);
+
+ return success;
+ }
+
+ /** consumes all elements via a functor
+ *
+ * sequentially pops all elements from the queue and applies the functor on each object
+ *
+ * \returns number of elements that are consumed
+ *
+ * \note Thread-safe and non-blocking, if functor is thread-safe and non-blocking
+ * */
+ template <typename Functor>
+ size_t consume_all(Functor & f)
+ {
+ size_t element_count = 0;
+ while (consume_one(f))
+ element_count += 1;
+
+ return element_count;
+ }
+
+ /// \copydoc boost::lockfree::queue::consume_all(Functor & rhs)
+ template <typename Functor>
+ size_t consume_all(Functor const & f)
+ {
+ size_t element_count = 0;
+ while (consume_one(f))
+ element_count += 1;
+
+ return element_count;
+ }
+
 private:
 #ifndef BOOST_DOXYGEN_INVOKED
     atomic<tagged_node_handle> head_;

Modified: branches/release/boost/lockfree/spsc_queue.hpp
==============================================================================
--- branches/release/boost/lockfree/spsc_queue.hpp (original)
+++ branches/release/boost/lockfree/spsc_queue.hpp 2013-03-24 09:08:34 EDT (Sun, 24 Mar 2013)
@@ -14,7 +14,9 @@
 
 #include <boost/array.hpp>
 #include <boost/assert.hpp>
+#ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS
 #include <boost/noncopyable.hpp>
+#endif
 #include <boost/static_assert.hpp>
 
 #include <boost/lockfree/detail/atomic.hpp>
@@ -32,8 +34,10 @@
> ringbuffer_signature;
 
 template <typename T>
-class ringbuffer_base:
- boost::noncopyable
+class ringbuffer_base
+#ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS
+ : boost::noncopyable
+#endif
 {
 #ifndef BOOST_DOXYGEN_INVOKED
     typedef std::size_t size_t;
@@ -42,6 +46,12 @@
     char padding1[padding_size]; /* force read_index and write_index to different cache lines */
     atomic<size_t> read_index_;
 
+#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS
+ ringbuffer_base(ringbuffer_base const &) = delete;
+ ringbuffer_base(ringbuffer_base &&) = delete;
+ const ringbuffer_base& operator=( const ringbuffer_base& ) = delete;
+#endif
+
 protected:
     ringbuffer_base(void):
         write_index_(0), read_index_(0)
@@ -641,6 +651,66 @@
     {
         return base_type::pop(it);
     }
+
+ /** consumes one element via a functor
+ *
+ * pops one element from the queue and applies the functor on this object
+ *
+ * \returns true, if one element was consumed
+ *
+ * \note Thread-safe and non-blocking, if functor is thread-safe and non-blocking
+ * */
+ template <typename Functor>
+ bool consume_one(Functor & f)
+ {
+ T element;
+ bool success = pop(element);
+ if (success)
+ f(element);
+
+ return success;
+ }
+
+ /// \copydoc boost::lockfree::spsc_queue::consume_one(Functor & rhs)
+ template <typename Functor>
+ bool consume_one(Functor const & f)
+ {
+ T element;
+ bool success = pop(element);
+ if (success)
+ f(element);
+
+ return success;
+ }
+
+ /** consumes all elements via a functor
+ *
+ * sequentially pops all elements from the queue and applies the functor on each object
+ *
+ * \returns number of elements that are consumed
+ *
+ * \note Thread-safe and non-blocking, if functor is thread-safe and non-blocking
+ * */
+ template <typename Functor>
+ size_type consume_all(Functor & f)
+ {
+ size_type element_count = 0;
+ while (consume_one(f))
+ element_count += 1;
+
+ return element_count;
+ }
+
+ /// \copydoc boost::lockfree::spsc_queue::consume_all(Functor & rhs)
+ template <typename Functor>
+ size_type consume_all(Functor const & f)
+ {
+ size_type element_count = 0;
+ while (consume_one(f))
+ element_count += 1;
+
+ return element_count;
+ }
 };
 
 } /* namespace lockfree */

Modified: branches/release/boost/lockfree/stack.hpp
==============================================================================
--- branches/release/boost/lockfree/stack.hpp (original)
+++ branches/release/boost/lockfree/stack.hpp 2013-03-24 09:08:34 EDT (Sun, 24 Mar 2013)
@@ -1,4 +1,4 @@
-// Copyright (C) 2008, 2009, 2010, 2011 Tim Blechmann
+// Copyright (C) 2008-2013 Tim Blechmann
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
@@ -10,7 +10,9 @@
 #include <boost/assert.hpp>
 #include <boost/checked_delete.hpp>
 #include <boost/integer_traits.hpp>
+#ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS
 #include <boost/noncopyable.hpp>
+#endif
 #include <boost/static_assert.hpp>
 #include <boost/tuple/tuple.hpp>
 #include <boost/type_traits/has_trivial_assign.hpp>
@@ -63,8 +65,10 @@
 #else
 template <typename T, ...Options>
 #endif
-class stack:
- boost::noncopyable
+class stack
+#ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS
+ : boost::noncopyable
+#endif
 {
 private:
 #ifndef BOOST_DOXYGEN_INVOKED
@@ -108,6 +112,12 @@
 
 #endif
 
+#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS
+ stack(stack const &) = delete;
+ stack(stack &&) = delete;
+ const stack& operator=( const stack& ) = delete;
+#endif
+
 public:
     typedef T value_type;
     typedef typename implementation_defined::allocator allocator;
@@ -484,6 +494,66 @@
         return true;
     }
 
+ /** consumes one element via a functor
+ *
+ * pops one element from the stack and applies the functor on this object
+ *
+ * \returns true, if one element was consumed
+ *
+ * \note Thread-safe and non-blocking, if functor is thread-safe and non-blocking
+ * */
+ template <typename Functor>
+ bool consume_one(Functor & f)
+ {
+ T element;
+ bool success = pop(element);
+ if (success)
+ f(element);
+
+ return success;
+ }
+
+ /// \copydoc boost::lockfree::stack::consume_one(Functor & rhs)
+ template <typename Functor>
+ bool consume_one(Functor const & f)
+ {
+ T element;
+ bool success = pop(element);
+ if (success)
+ f(element);
+
+ return success;
+ }
+
+ /** consumes all elements via a functor
+ *
+ * sequentially pops all elements from the stack and applies the functor on each object
+ *
+ * \returns number of elements that are consumed
+ *
+ * \note Thread-safe and non-blocking, if functor is thread-safe and non-blocking
+ * */
+ template <typename Functor>
+ size_t consume_all(Functor & f)
+ {
+ size_t element_count = 0;
+ while (consume_one(f))
+ element_count += 1;
+
+ return element_count;
+ }
+
+ /// \copydoc boost::lockfree::stack::consume_all(Functor & rhs)
+ template <typename Functor>
+ size_t consume_all(Functor const & f)
+ {
+ size_t element_count = 0;
+ while (consume_one(f))
+ element_count += 1;
+
+ return element_count;
+ }
+
     /**
      * \return true, if stack is empty.
      *

Modified: branches/release/libs/lockfree/test/queue_test.cpp
==============================================================================
--- branches/release/libs/lockfree/test/queue_test.cpp (original)
+++ branches/release/libs/lockfree/test/queue_test.cpp 2013-03-24 09:08:34 EDT (Sun, 24 Mar 2013)
@@ -16,6 +16,8 @@
 
 #include <memory>
 
+#include "test_helpers.hpp"
+
 using namespace boost;
 using namespace boost::lockfree;
 using namespace std;
@@ -82,6 +84,58 @@
 }
 
 
+BOOST_AUTO_TEST_CASE( queue_consume_one_test )
+{
+ queue<int> f(64);
+
+ BOOST_WARN(f.is_lock_free());
+ BOOST_REQUIRE(f.empty());
+
+ f.push(1);
+ f.push(2);
+
+#ifdef BOOST_NO_CXX11_LAMBDAS
+ bool success1 = f.consume_one(test_equal(1));
+ bool success2 = f.consume_one(test_equal(2));
+#else
+ bool success1 = f.consume_one([] (int i) {
+ BOOST_REQUIRE_EQUAL(i, 1);
+ });
+
+ bool success2 = f.consume_one([] (int i) {
+ BOOST_REQUIRE_EQUAL(i, 2);
+ });
+#endif
+
+ BOOST_REQUIRE(success1);
+ BOOST_REQUIRE(success2);
+
+ BOOST_REQUIRE(f.empty());
+}
+
+BOOST_AUTO_TEST_CASE( queue_consume_all_test )
+{
+ queue<int> f(64);
+
+ BOOST_WARN(f.is_lock_free());
+ BOOST_REQUIRE(f.empty());
+
+ f.push(1);
+ f.push(2);
+
+#ifdef BOOST_NO_CXX11_LAMBDAS
+ size_t consumed = f.consume_all(dummy_functor());
+#else
+ size_t consumed = f.consume_all([] (int i) {
+ });
+#endif
+
+ BOOST_REQUIRE_EQUAL(consumed, 2u);
+
+ BOOST_REQUIRE(f.empty());
+}
+
+
 BOOST_AUTO_TEST_CASE( queue_convert_pop_test )
 {
     queue<int*> f(128);

Modified: branches/release/libs/lockfree/test/spsc_queue_test.cpp
==============================================================================
--- branches/release/libs/lockfree/test/spsc_queue_test.cpp (original)
+++ branches/release/libs/lockfree/test/spsc_queue_test.cpp 2013-03-24 09:08:34 EDT (Sun, 24 Mar 2013)
@@ -6,8 +6,6 @@
 
 #include <boost/lockfree/spsc_queue.hpp>
 
-#include <boost/thread.hpp>
-
 #define BOOST_TEST_MAIN
 #ifdef BOOST_LOCKFREE_INCLUDE_TESTS
 #include <boost/test/included/unit_test.hpp>
@@ -75,6 +73,56 @@
     BOOST_REQUIRE(!stk.pop(out));
 }
 
+BOOST_AUTO_TEST_CASE( spsc_queue_consume_one_test )
+{
+ spsc_queue<int> f(64);
+
+ BOOST_WARN(f.is_lock_free());
+ BOOST_REQUIRE(f.empty());
+
+ f.push(1);
+ f.push(2);
+
+#ifdef BOOST_NO_CXX11_LAMBDAS
+ bool success1 = f.consume_one(test_equal(1));
+ bool success2 = f.consume_one(test_equal(2));
+#else
+ bool success1 = f.consume_one([] (int i) {
+ BOOST_REQUIRE_EQUAL(i, 1);
+ });
+
+ bool success2 = f.consume_one([] (int i) {
+ BOOST_REQUIRE_EQUAL(i, 2);
+ });
+#endif
+
+ BOOST_REQUIRE(success1);
+ BOOST_REQUIRE(success2);
+
+ BOOST_REQUIRE(f.empty());
+}
+
+BOOST_AUTO_TEST_CASE( spsc_queue_consume_all_test )
+{
+ spsc_queue<int> f(64);
+
+ BOOST_WARN(f.is_lock_free());
+ BOOST_REQUIRE(f.empty());
+
+ f.push(1);
+ f.push(2);
+
+#ifdef BOOST_NO_CXX11_LAMBDAS
+ size_t consumed = f.consume_all(dummy_functor());
+#else
+ size_t consumed = f.consume_all([] (int i) {
+ });
+#endif
+
+ BOOST_REQUIRE_EQUAL(consumed, 2u);
+
+ BOOST_REQUIRE(f.empty());
+}
 
 enum {
     pointer_and_size,
@@ -93,7 +141,7 @@
 
     int data[xqueue_size];
     for (size_t i = 0; i != xqueue_size; ++i)
- data[i] = i*2;
+ data[i] = (int)i*2;
 
     switch (EnqueueMode) {
     case pointer_and_size:
@@ -149,7 +197,7 @@
 
     int data[xqueue_size];
     for (size_t i = 0; i != xqueue_size; ++i)
- data[i] = i*2;
+ data[i] = (int)i*2;
 
     std::vector<int> vdata(data, data + xqueue_size);
 
@@ -198,7 +246,7 @@
 
     int data[xqueue_size];
     for (size_t i = 0; i != xqueue_size; ++i)
- data[i] = i*2;
+ data[i] = (int)i*2;
 
     std::vector<int> vdata(data, data + xqueue_size);
 
@@ -243,189 +291,3 @@
     spsc_queue_buffer_pop<reference_to_array, 7, 16, 64>();
     spsc_queue_buffer_pop<output_iterator_, 7, 16, 64>();
 }
-
-
-#ifndef BOOST_LOCKFREE_STRESS_TEST
-static const boost::uint32_t nodes_per_thread = 100000;
-#else
-static const boost::uint32_t nodes_per_thread = 100000000;
-#endif
-
-struct spsc_queue_tester
-{
- spsc_queue<int, capacity<128> > sf;
-
- boost::lockfree::detail::atomic<long> spsc_queue_cnt, received_nodes;
-
- static_hashed_set<int, 1<<16 > working_set;
-
- spsc_queue_tester(void):
- spsc_queue_cnt(0), received_nodes(0)
- {}
-
- void add(void)
- {
- for (boost::uint32_t i = 0; i != nodes_per_thread; ++i) {
- int id = generate_id<int>();
- working_set.insert(id);
-
- while (sf.push(id) == false)
- {}
-
- ++spsc_queue_cnt;
- }
- running = false;
- }
-
- bool get_element(void)
- {
- int data;
- bool success = sf.pop(data);
-
- if (success) {
- ++received_nodes;
- --spsc_queue_cnt;
- bool erased = working_set.erase(data);
- assert(erased);
- return true;
- } else
- return false;
- }
-
- boost::lockfree::detail::atomic<bool> running;
-
- void get(void)
- {
- for(;;) {
- bool success = get_element();
- if (!running && !success)
- break;
- }
-
- while ( get_element() );
- }
-
- void run(void)
- {
- running = true;
-
- BOOST_REQUIRE(sf.empty());
-
- thread reader(boost::bind(&spsc_queue_tester::get, this));
- thread writer(boost::bind(&spsc_queue_tester::add, this));
- cout << "reader and writer threads created" << endl;
-
- writer.join();
- cout << "writer threads joined. waiting for readers to finish" << endl;
-
- reader.join();
-
- BOOST_REQUIRE_EQUAL(received_nodes, nodes_per_thread);
- BOOST_REQUIRE_EQUAL(spsc_queue_cnt, 0);
- BOOST_REQUIRE(sf.empty());
- BOOST_REQUIRE(working_set.count_nodes() == 0);
- }
-};
-
-BOOST_AUTO_TEST_CASE( spsc_queue_test_caching )
-{
- boost::shared_ptr<spsc_queue_tester> test1(new spsc_queue_tester);
- test1->run();
-}
-
-struct spsc_queue_tester_buffering
-{
- spsc_queue<int, capacity<128> > sf;
-
- boost::lockfree::detail::atomic<long> spsc_queue_cnt;
-
- static_hashed_set<int, 1<<16 > working_set;
- boost::lockfree::detail::atomic<long> received_nodes;
-
- spsc_queue_tester_buffering(void):
- spsc_queue_cnt(0), received_nodes(0)
- {}
-
- static const size_t buf_size = 5;
-
- void add(void)
- {
- boost::array<int, buf_size> input_buffer;
- for (boost::uint32_t i = 0; i != nodes_per_thread; i+=buf_size) {
- for (size_t i = 0; i != buf_size; ++i) {
- int id = generate_id<int>();
- working_set.insert(id);
- input_buffer[i] = id;
- }
-
- size_t pushed = 0;
-
- do {
- pushed += sf.push(input_buffer.c_array() + pushed,
- input_buffer.size() - pushed);
- } while (pushed != buf_size);
-
- spsc_queue_cnt+=buf_size;
- }
- running = false;
- }
-
- bool get_elements(void)
- {
- boost::array<int, buf_size> output_buffer;
-
- size_t popd = sf.pop(output_buffer.c_array(), output_buffer.size());
-
- if (popd) {
- received_nodes += popd;
- spsc_queue_cnt -= popd;
-
- for (size_t i = 0; i != popd; ++i) {
- bool erased = working_set.erase(output_buffer[i]);
- assert(erased);
- }
-
- return true;
- } else
- return false;
- }
-
- boost::lockfree::detail::atomic<bool> running;
-
- void get(void)
- {
- for(;;) {
- bool success = get_elements();
- if (!running && !success)
- break;
- }
-
- while ( get_elements() );
- }
-
- void run(void)
- {
- running = true;
-
- thread reader(boost::bind(&spsc_queue_tester_buffering::get, this));
- thread writer(boost::bind(&spsc_queue_tester_buffering::add, this));
- cout << "reader and writer threads created" << endl;
-
- writer.join();
- cout << "writer threads joined. waiting for readers to finish" << endl;
-
- reader.join();
-
- BOOST_REQUIRE_EQUAL(received_nodes, nodes_per_thread);
- BOOST_REQUIRE_EQUAL(spsc_queue_cnt, 0);
- BOOST_REQUIRE(sf.empty());
- BOOST_REQUIRE(working_set.count_nodes() == 0);
- }
-};
-
-
-BOOST_AUTO_TEST_CASE( spsc_queue_test_buffering )
-{
- boost::shared_ptr<spsc_queue_tester_buffering> test1(new spsc_queue_tester_buffering);
- test1->run();
-}

Modified: branches/release/libs/lockfree/test/stack_test.cpp
==============================================================================
--- branches/release/libs/lockfree/test/stack_test.cpp (original)
+++ branches/release/libs/lockfree/test/stack_test.cpp 2013-03-24 09:08:34 EDT (Sun, 24 Mar 2013)
@@ -15,6 +15,8 @@
 #include <boost/test/unit_test.hpp>
 #endif
 
+#include "test_helpers.hpp"
+
 BOOST_AUTO_TEST_CASE( simple_stack_test )
 {
     boost::lockfree::stack<long> stk(128);
@@ -107,3 +109,54 @@
     BOOST_REQUIRE(!stk.pop(out));
     BOOST_REQUIRE(stk.empty());
 }
+
+BOOST_AUTO_TEST_CASE( stack_consume_one_test )
+{
+ boost::lockfree::stack<int> f(64);
+
+ BOOST_WARN(f.is_lock_free());
+ BOOST_REQUIRE(f.empty());
+
+ f.push(1);
+ f.push(2);
+
+#ifdef BOOST_NO_CXX11_LAMBDAS
+ bool success1 = f.consume_one(test_equal(2));
+ bool success2 = f.consume_one(test_equal(1));
+#else
+ bool success1 = f.consume_one([] (int i) {
+ BOOST_REQUIRE_EQUAL(i, 2);
+ });
+
+ bool success2 = f.consume_one([] (int i) {
+ BOOST_REQUIRE_EQUAL(i, 1);
+ });
+#endif
+
+ BOOST_REQUIRE(success1);
+ BOOST_REQUIRE(success2);
+
+ BOOST_REQUIRE(f.empty());
+}
+
+BOOST_AUTO_TEST_CASE( stack_consume_all_test )
+{
+ boost::lockfree::stack<int> f(64);
+
+ BOOST_WARN(f.is_lock_free());
+ BOOST_REQUIRE(f.empty());
+
+ f.push(1);
+ f.push(2);
+
+#ifdef BOOST_NO_CXX11_LAMBDAS
+ size_t consumed = f.consume_all(dummy_functor());
+#else
+ size_t consumed = f.consume_all([] (int i) {
+ });
+#endif
+
+ BOOST_REQUIRE_EQUAL(consumed, 2u);
+
+ BOOST_REQUIRE(f.empty());
+}

Modified: branches/release/libs/lockfree/test/test_helpers.hpp
==============================================================================
--- branches/release/libs/lockfree/test/test_helpers.hpp (original)
+++ branches/release/libs/lockfree/test/test_helpers.hpp 2013-03-24 09:08:34 EDT (Sun, 24 Mar 2013)
@@ -85,4 +85,26 @@
     mutable boost::array<boost::mutex, buckets> ref_mutex;
 };
 
+struct test_equal
+{
+ test_equal(int i):
+ i(i)
+ {}
+
+ void operator()(int arg) const
+ {
+ BOOST_REQUIRE_EQUAL(arg, i);
+ }
+
+ int i;
+};
+
+struct dummy_functor
+{
+ void operator()(int arg) const
+ {
+ }
+};
+
+
 #endif


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