$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r86736 - in trunk: boost/lockfree libs/lockfree/test
From: tim_at_[hidden]
Date: 2013-11-17 05:49:47
Author: timblechmann
Date: 2013-11-17 05:49:47 EST (Sun, 17 Nov 2013)
New Revision: 86736
URL: http://svn.boost.org/trac/boost/changeset/86736
Log:
lockfree: spsc-queue - add read_available and write_available members
Text files modified: 
   trunk/boost/lockfree/spsc_queue.hpp          |    50 +++++++++++++++++++++++++++++++++++++++ 
   trunk/libs/lockfree/test/spsc_queue_test.cpp |    35 ++++++++++++++++++++++++++++            
   2 files changed, 84 insertions(+), 1 deletions(-)
Modified: trunk/boost/lockfree/spsc_queue.hpp
==============================================================================
--- trunk/boost/lockfree/spsc_queue.hpp	Sun Nov 17 05:49:15 2013	(r86735)
+++ trunk/boost/lockfree/spsc_queue.hpp	2013-11-17 05:49:47 EST (Sun, 17 Nov 2013)	(r86736)
@@ -68,7 +68,7 @@
         if (write_index >= read_index)
             return write_index - read_index;
 
-        size_t ret = write_index + max_size - read_index;
+        const size_t ret = write_index + max_size - read_index;
         return ret;
     }
 
@@ -80,6 +80,20 @@
         return ret;
     }
 
+    size_t read_available(size_t max_size) const
+    {
+        size_t write_index = write_index_.load(memory_order_relaxed);
+        const size_t read_index  = read_index_.load(memory_order_relaxed);
+        return read_available(write_index, read_index, max_size);
+    }
+
+    size_t write_available(size_t max_size) const
+    {
+        size_t write_index = write_index_.load(memory_order_relaxed);
+        const size_t read_index  = read_index_.load(memory_order_relaxed);
+        return write_available(write_index, read_index, max_size);
+    }
+
     bool push(T const & t, T * buffer, size_t max_size)
     {
         const size_t write_index = write_index_.load(memory_order_relaxed);  // only written from push thread
@@ -288,6 +302,12 @@
         return static_cast<T*>(storage_.address());
     }
 
+protected:
+    size_t max_number_of_elements() const
+    {
+        return max_size;
+    }
+
 public:
     bool push(T const & t)
     {
@@ -344,6 +364,12 @@
     typedef typename Alloc::pointer pointer;
     pointer array_;
 
+protected:
+    size_t max_number_of_elements() const
+    {
+        return max_elements_;
+    }
+
 public:
     explicit runtime_sized_ringbuffer(size_type max_elements):
         max_elements_(max_elements + 1)
@@ -701,6 +727,28 @@
 
         return element_count;
     }
+
+    /** get number of elements that are available for read
+     *
+     * \return number of available elements that can be popped from the spsc_queue
+     *
+     * \note Thread-safe and wait-free, should only be called from the producer thread
+     * */
+    size_type read_available() const
+    {
+        return base_type::read_available(base_type::max_number_of_elements());
+    }
+
+    /** get write space to write elements
+     *
+     * \return number of elements that can be pushed to the spsc_queue
+     *
+     * \note Thread-safe and wait-free, should only be called from the consumer thread
+     * */
+    size_type write_available() const
+    {
+        return base_type::write_available(base_type::max_number_of_elements());
+    }
 };
 
 } /* namespace lockfree */
Modified: trunk/libs/lockfree/test/spsc_queue_test.cpp
==============================================================================
--- trunk/libs/lockfree/test/spsc_queue_test.cpp	Sun Nov 17 05:49:15 2013	(r86735)
+++ trunk/libs/lockfree/test/spsc_queue_test.cpp	2013-11-17 05:49:47 EST (Sun, 17 Nov 2013)	(r86736)
@@ -146,6 +146,41 @@
     BOOST_REQUIRE(!g.push(3));
 }
 
+template <typename QueueType>
+void spsc_queue_avail_test_run(QueueType & q)
+{
+    BOOST_REQUIRE_EQUAL( q.write_available(), 16 );
+    BOOST_REQUIRE_EQUAL( q.read_available(),   0 );
+
+    for (size_t i = 0; i != 8; ++i) {
+        BOOST_REQUIRE_EQUAL( q.write_available(), 16 - i );
+        BOOST_REQUIRE_EQUAL( q.read_available(),       i );
+
+        q.push( 1 );
+    }
+
+    // empty queue
+    int dummy;
+    while (q.pop(dummy))
+    {}
+
+    for (size_t i = 0; i != 16; ++i) {
+        BOOST_REQUIRE_EQUAL( q.write_available(), 16 - i );
+        BOOST_REQUIRE_EQUAL( q.read_available(),       i );
+
+        q.push( 1 );
+    }
+}
+
+BOOST_AUTO_TEST_CASE( spsc_queue_avail_test )
+{
+    spsc_queue<int, capacity<16> > f;
+    spsc_queue_avail_test_run(f);
+
+    spsc_queue<int> g(16);
+    spsc_queue_avail_test_run(g);
+}
+
 
 template <int EnqueueMode>
 void spsc_queue_buffer_push_return_value(void)