Boost logo

Boost-Commit :

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)


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