VyukovMPMCCycleQueue refactoring
authorkhizmax <libcds.dev@gmail.com>
Sun, 12 Oct 2014 14:40:42 +0000 (18:40 +0400)
committerkhizmax <libcds.dev@gmail.com>
Sun, 12 Oct 2014 14:40:42 +0000 (18:40 +0400)
25 files changed:
cds/container/tsigas_cycle_queue.h
cds/container/vyukov_mpmc_cycle_queue.h
cds/intrusive/vyukov_mpmc_cycle_queue.h
cds/memory/michael/allocator.h
cds/memory/vyukov_queue_pool.h
cds/urcu/details/gpb.h
cds/urcu/details/gpt.h
cds/urcu/details/sig_buffered.h
cds/urcu/details/sig_threaded.h
cds/urcu/general_buffered.h
cds/urcu/general_threaded.h
cds/urcu/signal_buffered.h
cds/urcu/signal_threaded.h
tests/test-hdr/queue/hdr_intrusive_msqueue.h
tests/test-hdr/queue/hdr_intrusive_vyukovmpmc_cycle_queue.cpp
tests/test-hdr/queue/hdr_queue.h
tests/test-hdr/queue/hdr_queue_new.h
tests/test-hdr/queue/hdr_tsigas_cycle_queue.cpp
tests/test-hdr/queue/hdr_vyukov_mpmc_cyclic.cpp
tests/test-hdr/tree/hdr_intrusive_ellen_bintree_pool_hp.h
tests/test-hdr/tree/hdr_intrusive_ellen_bintree_pool_ptb.h
tests/test-hdr/tree/hdr_intrusive_ellen_bintree_pool_rcu.h
tests/unit/ellen_bintree_update_desc_pool.h
tests/unit/queue/intrusive_queue_type.h
tests/unit/queue/queue_type.h

index fd6b41f51561bd3d45eaa2bce30f55262f22e3a6..7c46531a96add8f1142d13b619be1960c839e413 100644 (file)
@@ -19,10 +19,10 @@ namespace cds { namespace container {
         {
             /// Buffer type for cyclic array
             /*
-            The type of element for the buffer is not important: the queue rebinds
-            buffer for required type via \p rebind metafunction.
+                The type of element for the buffer is not important: the queue rebinds
+                buffer for required type via \p rebind metafunction.
 
-            For \p TsigasCycleQueue queue the buffer size should have power-of-2 size.
+                For \p TsigasCycleQueue queue the buffer size should have power-of-2 size.
             */
             typedef cds::opt::v::dynamic_buffer< void * > buffer;
 
@@ -37,8 +37,8 @@ namespace cds { namespace container {
 
             /// C++ memory ordering model
             /**
-            Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
-            or \p opt::v::sequential_consistent (sequentially consisnent memory model).
+                Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
+                or \p opt::v::sequential_consistent (sequentially consisnent memory model).
             */
             typedef opt::v::relaxed_ordering    memory_model;
 
@@ -54,8 +54,6 @@ namespace cds { namespace container {
                 element in the buffer is not important: it will be changed via \p rebind metafunction.
             - \p opt::allocator - allocator (like \p std::allocator) used for allocating queue items. Default is \ref CDS_DEFAULT_ALLOCATOR
             - \p opt::back_off - back-off strategy used, default is \p cds::backoff::empty.
-            - \p opt::disposer - the functor used for dispose removed items. Default is \p opt::v::empty_disposer. This option is used
-                when dequeuing.
             - \p opt::item_counter - the type of item counting feature. Default is \p cds::atomicity::empty_item_counter (item counting disabled)
                 To enable item counting use \p cds::atomicity::item_counter
             - \p opt::alignment - the alignment for internal queue data. Default is \p opt::cache_line_alignment
@@ -305,7 +303,6 @@ namespace cds { namespace container {
             return enqueue_with( f );
         }
 
-
         /// Dequeues a value using a functor
         /**
             \p Func is a functor called to copy dequeued value.
index 2c2a7bf9bfaf5720ca015e70a2bc14fcc8e984d5..30095b707c7bf63ebafa82bb0ed9bc11e430885e 100644 (file)
@@ -3,16 +3,95 @@
 #ifndef __CDS_CONTAINER_VYUKOV_MPMC_CYCLE_QUEUE_H
 #define __CDS_CONTAINER_VYUKOV_MPMC_CYCLE_QUEUE_H
 
-#include <functional>   // ref
 #include <cds/container/details/base.h>
 #include <cds/opt/buffer.h>
 #include <cds/opt/value_cleaner.h>
 #include <cds/cxx11_atomic.h>
-#include <cds/details/trivial_assign.h>
 #include <cds/details/bounded_container.h>
 
 namespace cds { namespace container {
 
+    /// VyukovMPMCCycleQueue related definitions
+    /** @ingroup cds_nonintrusive_helper
+    */
+    namespace vyukov_queue {
+
+        /// VyukovMPMCCycleQueue default traits
+        struct traits {
+            /// Buffer type for internal array
+            /*
+                The type of element for the buffer is not important: the queue rebinds
+                buffer for required type via \p rebind metafunction.
+
+                For \p VyukovMPMCCycleQueue queue the buffer size should have power-of-2 size.
+            */
+            typedef cds::opt::v::dynamic_buffer< void * > buffer;
+
+            /// A functor to clean item dequeued. 
+            /**
+                The functor  calls the destructor for queue item.
+                After an item is dequeued, \p value_cleaner cleans the cell that the item has been occupied.
+                If \p T is a complex type, \p value_cleaner may be the useful feature.
+
+                Default value is \ref opt::v::destruct_cleaner
+            */
+            typedef cds::opt::v::destruct_cleaner value_cleaner;
+
+            /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter to enable item counting
+            typedef cds::atomicity::empty_item_counter item_counter;
+
+            /// C++ memory ordering model
+            /**
+                Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
+                or \p opt::v::sequential_consistent (sequentially consisnent memory model).
+            */
+            typedef opt::v::relaxed_ordering    memory_model;
+
+            /// Alignment for internal queue data. Default is \p opt::cache_line_alignment
+            enum { alignment = opt::cache_line_alignment };
+        };
+
+        /// Metafunction converting option list to \p vyukov_queue::traits
+        /**
+            Supported \p Options are:
+            - \p opt::buffer - the buffer type for internal cyclic array. Possible types are:
+                \p opt::v::dynamic_buffer (the default), \p opt::v::static_buffer. The type of
+                element in the buffer is not important: it will be changed via \p rebind metafunction.
+            - \p opt::value_cleaner - a functor to clean item dequeued. 
+                The functor calls the destructor for queue item.
+                After an item is dequeued, \p value_cleaner cleans the cell that the item has been occupied.
+                If \p T is a complex type, \p value_cleaner may be the useful feature.
+                Default value is \ref opt::v::destruct_cleaner
+            - \p opt::item_counter - the type of item counting feature. Default is \p cds::atomicity::empty_item_counter (item counting disabled)
+                To enable item counting use \p cds::atomicity::item_counter
+            - \p opt::alignment - the alignment for internal queue data. Default is \p opt::cache_line_alignment
+            - \p opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
+                or \p opt::v::sequential_consistent (sequentially consisnent memory model).
+
+            Example: declare \p %VyukovMPMCCycleQueue with item counting and static iternal buffer of size 1024:
+            \code
+            typedef cds::container::VyukovMPMCCycleQueue< Foo, 
+                typename cds::container::vyukov_queue::make_traits<
+                    cds::opt::buffer< cds::opt::v::static_buffer< void *, 1024 >,
+                    cds::opt::item_counte< cds::atomicity::item_counter >
+                >::type
+            > myQueue;
+            \endcode
+        */
+        template <typename... Options>
+        struct make_traits {
+#   ifdef CDS_DOXYGEN_INVOKED
+            typedef implementation_defined type;   ///< Metafunction result
+#   else
+            typedef typename cds::opt::make_options<
+                typename cds::opt::find_type_traits< traits, Options... >::type
+                , Options...
+            >::type type;
+#   endif
+        };
+
+    } //namespace vyukov_queue
+
     /// Vyukov's MPMC bounded queue
     /** @ingroup cds_nonintrusive_queue
         This algorithm is developed by Dmitry Vyukov (see http://www.1024cores.net)
@@ -24,76 +103,44 @@ namespace cds { namespace container {
         No dynamic memory allocation/management during operation. Producers and consumers are separated from each other (as in the two-lock queue),
         i.e. do not touch the same data while queue is not empty.
 
-        \par Source:
-            http://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue
-
-        \par Template parameters
-            \li \p T - type stored in queue.
-            \li \p Options - queue's options
+        Source:
+            - http://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue
 
-        Options \p Options are:
-        - opt::buffer - buffer to store items. Mandatory option, see option description for full list of possible types.
-        - opt::item_counter - the type of item counting feature. Default is \ref atomicity::empty_item_counter
-        - opt::value_cleaner - a functor to clean item dequeued. Default value is \ref opt::v::destruct_cleaner
-            that calls the destructor of type \p T.
-            After an item is dequeued, \p value_cleaner cleans the cell that the item has been occupied. If \p T
-            is a complex type, \p value_cleaner may be the useful feature.
-        - opt::alignment - the alignment for internal queue data. Default is opt::cache_line_alignment
-        - opt::memory_model - C++ memory ordering model. Can be opt::v::relaxed_ordering (relaxed memory model, the default)
-            or opt::v::sequential_consistent (sequentially consisnent memory model).
+        Template parameters
+        - \p T - type stored in queue.
+        - \p Traits - queue traits, default is \p vykov_queue::traits. You can use \p vykov_queue::make_traits
+            metafunction to make your traits or just derive your traits from \p %vykov_queue::traits:
+            \code
+            struct myTraits: public cds::container::vykov_queue::traits {
+                typedef cds::atomicity::item_counter    item_counter;
+            };
+            typedef cds::container::VyukovMPMCCycleQueue< Foo, myTraits > myQueue;
+
+            // Equivalent make_traits example:
+            typedef cds::container::VyukovMPMCCycleQueue< cds::gc::HP, Foo, 
+                typename cds::container::vykov_queue::make_traits< 
+                    cds::opt::item_counter< cds::atomicity::item_counter >
+                >::type
+            > myQueue;
+            \endcode
 
         \par License
             Simplified BSD license by Dmitry Vyukov (http://www.1024cores.net/site/1024cores/home/code-license)
-
-        \par Example
-        \code
-        #include <cds/container/vyukov_mpmc_cycle_queue.h>
-
-        // // Queue with 1024 item static buffer
-        cds::container::vyukov_mpmc_bounded<
-            int
-            ,cds::opt::buffer< cds::opt::v::static_buffer<int, 1024> >
-        > myQueue;
-        \endcode
     */
-    template <typename T, typename... Options>
-    class VyukovMPMCCycleQueue
-        : public cds::bounded_container
+    template <typename T, typename Traits = vyukov_queue::traits >
+    class VyukovMPMCCycleQueue : public cds::bounded_container
     {
-    protected:
-        //@cond
-        struct default_options
-        {
-            typedef cds::opt::v::destruct_cleaner  value_cleaner;
-            typedef atomicity::empty_item_counter item_counter;
-            typedef opt::v::empty_disposer      disposer    ;   // for intrusive version only
-            typedef opt::v::relaxed_ordering    memory_model;
-            enum { alignment = opt::cache_line_alignment };
-        };
-        //@endcond
-
-    public:
-        //@cond
-        typedef typename opt::make_options<
-            typename cds::opt::find_type_traits< default_options, Options... >::type
-            ,Options...
-        >::type   options;
-        //@endcond
-
-    protected:
-        //@cond
-        typedef typename options::value_cleaner  value_cleaner;
-        //@endcond
-
     public:
-        typedef T value_type    ;   ///< @anchor cds_container_VyukovMPMCCycleQueue_value_type type of value stored in the queue
-        typedef typename options::item_counter  item_counter ;  ///< Item counter type
-        typedef typename options::memory_model  memory_model ;  ///< Memory ordering. See cds::opt::memory_model option
+        typedef T value_type;   ///< Value type to be stored in the queue
+        typedef Traits traits;  ///< Queue traits
+        typedef typename traits::item_counter  item_counter;  ///< Item counter type
+        typedef typename traits::memory_model  memory_model;  ///< Memory ordering. See cds::opt::memory_model option
+        typedef typename traits::value_cleaner value_cleaner; ///< Value cleaner, see \p vyukov_queue::traits::value_cleaner
 
         /// Rebind template arguments
-        template <typename T2, typename... Options2>
+        template <typename T2, typename Traits2>
         struct rebind {
-            typedef VyukovMPMCCycleQueue< T2, Options2...> other   ;   ///< Rebinding result
+            typedef VyukovMPMCCycleQueue< T2, Traits2 > other   ;   ///< Rebinding result
         };
 
     protected:
@@ -108,11 +155,9 @@ namespace cds { namespace container {
             {}
         };
 
-        typedef cds::details::trivial_assign< value_type, value_type > copy_assign;
-
-        typedef typename options::buffer::template rebind<cell_type>::other buffer;
-        typedef typename opt::details::alignment_setter< sequence_type, options::alignment >::type aligned_sequence_type;
-        typedef typename opt::details::alignment_setter< buffer, options::alignment >::type aligned_buffer;
+        typedef typename traits::buffer::template rebind<cell_type>::other buffer;
+        typedef typename opt::details::alignment_setter< sequence_type, traits::alignment >::type aligned_sequence_type;
+        typedef typename opt::details::alignment_setter< buffer, traits::alignment >::type aligned_buffer;
         //@endcond
 
     protected:
@@ -127,7 +172,7 @@ namespace cds { namespace container {
     public:
         /// Constructs the queue of capacity \p nCapacity
         /**
-            For cds::opt::v::static_buffer the \p nCapacity parameter is ignored.
+            For \p cds::opt::v::static_buffer the \p nCapacity parameter is ignored.
         */
         VyukovMPMCCycleQueue(
             size_t nCapacity = 0
@@ -152,26 +197,18 @@ namespace cds { namespace container {
             clear();
         }
 
-        /// Enqueues \p data to queue using copy functor
-        /** @anchor cds_container_VyukovMPMCCycleQueue_enqueue_func
-            \p Func is a functor called to copy value \p data of type \p Source
-            which may be differ from type \p T stored in the queue.
-            The functor's interface is:
+        /// Enqueues data to the queue using a functor
+        /**
+            \p Func is a functor called to copy a value to the queue cell.
+            The functor \p f takes one argument - a reference to a empty cell of type \ref value_type :
             \code
-                struct myFunctor {
-                    void operator()(T& dest, Source const& data)
-                    {
-                        // // Code to copy \p data to \p dest
-                        dest = data;
-                    }
-                };
+            cds::container::VyukovMPMCCycleQueue< Foo > myQueue;
+            Bar bar;
+            myQueue.enqueue_with( [&bar]( Foo& dest ) { dest = std::move(bar); } );
             \endcode
-            You may use \p boost:ref construction to pass functor \p f by reference.
-
-            <b>Requirements</b> The functor \p Func should not throw any exception.
         */
-        template <typename Source, typename Func>
-        bool enqueue(Source const& data, Func func)
+        template <typename Func>
+        bool enqueue_with(Func f)
         {
             cell_type* cell;
             size_t pos = m_posEnqueue.load(memory_model::memory_order_relaxed);
@@ -194,7 +231,7 @@ namespace cds { namespace container {
                     pos = m_posEnqueue.load(memory_model::memory_order_relaxed);
             }
 
-            func( cell->data, data );
+            f( cell->data );
 
             cell->sequence.store(pos + 1, memory_model::memory_order_release);
             ++m_ItemCounter;
@@ -202,13 +239,30 @@ namespace cds { namespace container {
             return true;
         }
 
-        /// @anchor cds_container_VyukovMPMCCycleQueue_enqueue Enqueues \p data to queue
-        bool enqueue(value_type const& data )
+        /// Enqueues \p val value into the queue.
+        /**
+            The new queue item is created by calling placement new in free cell.
+            Returns \p true if success, \p false if the queue is full.
+        */
+        bool enqueue( value_type const& val )
         {
-            return enqueue( data, [](value_type& dest, value_type const& src){ new ( &dest ) value_type( src ); });
+            return enqueue_with( [&val]( value_type& dest ){ new ( &dest ) value_type( val ); });
         }
 
-        /// Enqueues data of type \ref cds_container_VyukovMPMCCycleQueue_value_type "value_type" constructed with <tt>std::forward<Args>(args)...</tt>
+        /// Synonym for \p enqueue()
+        bool push( value_type const& data )
+        {
+            return enqueue( data );
+        }
+
+        /// Synonym for \p enqueue_with()
+        template <typename Func>
+        bool push_with( Func f )
+        {
+            return enqueue_with( f );
+        }
+
+        /// Enqueues data of type \ref value_type constructed with <tt>std::forward<Args>(args)...</tt>
         template <typename... Args>
         bool emplace( Args&&... args )
         {
@@ -241,25 +295,19 @@ namespace cds { namespace container {
             return true;
         }
 
-        /// Dequeues an item from queue
-        /** @anchor cds_container_VyukovMPMCCycleQueue_dequeue_func
-            \p Func is a functor called to copy dequeued value of type \p T to \p dest of type \p Dest.
-            The functor's interface is:
+        /// Dequeues a value using a functor
+        /**
+            \p Func is a functor called to copy dequeued value.
+            The functor takes one argument - a reference to removed node:
             \code
-            struct myFunctor {
-            void operator()(Dest& dest, T const& data)
-            {
-                // // Code to copy \p data to \p dest
-                dest = data;
-            }
-            };
+            cds:container::VyukovMPMCCycleQueue< Foo > myQueue;
+            Bar bar;
+            myQueue.dequeue_with( [&bar]( Foo& src ) { bar = std::move( src );});
             \endcode
-            You may use \p boost:ref construction to pass functor \p func by reference.
-
-            <b>Requirements</b> The functor \p Func should not throw any exception.
+            The functor is called only if the queue is not empty.
         */
-        template <typename Dest, typename Func>
-        bool dequeue( Dest& data, Func func )
+        template <typename Func>
+        bool dequeue_with( Func f )
         {
             cell_type * cell;
             size_t pos = m_posDequeue.load(memory_model::memory_order_relaxed);
@@ -280,7 +328,7 @@ namespace cds { namespace container {
                     pos = m_posDequeue.load(memory_model::memory_order_relaxed);
             }
 
-            func( data, cell->data );
+            f( cell->data );
             value_cleaner()( cell->data );
             --m_ItemCounter;
             cell->sequence.store( pos + m_nBufferMask + 1, memory_model::memory_order_release );
@@ -288,39 +336,28 @@ namespace cds { namespace container {
             return true;
         }
 
-        /// Dequeues an item from queue to \p data
-        /** @anchor cds_container_VyukovMPMCCycleQueue_dequeue
-            If queue is empty, returns \p false, \p data is unchanged.
+        /// Dequeues a value from the queue
+        /**
+            If queue is not empty, the function returns \p true, \p dest contains copy of
+            dequeued value. The assignment operator for type \ref value_type is invoked.
+            If queue is empty, the function returns \p false, \p dest is unchanged.
         */
-        bool dequeue(value_type & data )
-        {
-            return dequeue( data, copy_assign() );
-        }
-
-        /// Synonym of \ref cds_container_VyukovMPMCCycleQueue_enqueue "enqueue"
-        bool push(value_type const& data)
-        {
-            return enqueue(data);
-        }
-
-        /// Synonym for template version of \ref cds_container_VyukovMPMCCycleQueue_enqueue_func "enqueue" function
-        template <typename Source, typename Func>
-        bool push( const Source& data, Func f  )
+        bool dequeue(value_type & dest )
         {
-            return enqueue( data, f );
+            return dequeue_with( [&dest]( value_type& src ){ dest = src; } );
         }
 
-        /// Synonym of \ref cds_container_VyukovMPMCCycleQueue_dequeue "dequeue"
+        /// Synonym for \p dequeue()
         bool pop(value_type& data)
         {
             return dequeue(data);
         }
 
-        /// Synonym for template version of \ref cds_container_VyukovMPMCCycleQueue_dequeue_func "dequeue" function
-        template <typename Type, typename Func>
-        bool pop( Type& dest, Func f )
+        /// Synonym for \p dequeue_with()
+        template <typename Func>
+        bool pop_with( Func f )
         {
-            return dequeue( dest, f );
+            return dequeue_with( f );
         }
 
         /// Checks if the queue is empty
@@ -353,15 +390,15 @@ namespace cds { namespace container {
 
         /// Returns queue's item count
         /**
-            The value returned depends on opt::item_counter option. For atomicity::empty_item_counter,
-            this function always returns 0.
+            The value returned depends on \p vyukov_queue::traits::item_counter option.
+            For \p atomicity::empty_item_counter, this function always returns 0.
         */
         size_t size() const
         {
             return m_ItemCounter.value();
         }
 
-        /// Returns capacity of cyclic buffer
+        /// Returns capacity of the queue
         size_t capacity() const
         {
             return m_buffer.capacity();
index 03382df37a2496ed9b8f784a459420c84acbb60e..0147f54333fde441c093ea87abf8f70e49edbd9e 100644 (file)
@@ -8,25 +8,77 @@
 
 namespace cds { namespace intrusive {
 
+    /// VyukovMPMCCycleQueue related definitions
+    /** @ingroup cds_intrusive_helper
+    */
+    namespace vyukov_queue {
+        struct traits : public cds::container::vyukov_queue::traits
+        {
+            /// The functor used for dispose removed items. Default is \p opt::v::empty_disposer. This option is used only in \p clear()
+            typedef opt::v::empty_disposer  disposer;
+        };
+
+        /// Metafunction converting option list to \p vyukov_queue::traits
+        /**
+            Supported \p Options are:
+            - \p opt::buffer - the buffer type for internal cyclic array. Possible types are:
+                \p opt::v::dynamic_buffer (the default), \p opt::v::static_buffer. The type of
+                element in the buffer is not important: it will be changed via \p rebind metafunction.
+            - \p opt::disposer - the functor used for dispose removed items. Default is \p opt::v::empty_disposer. 
+                This option is used only in \p clear() member function.
+            - \p opt::item_counter - the type of item counting feature. Default is \p cds::atomicity::empty_item_counter (item counting disabled)
+                To enable item counting use \p cds::atomicity::item_counter
+            - \p opt::alignment - the alignment for internal queue data. Default is \p opt::cache_line_alignment
+            - \p opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
+                or \p opt::v::sequential_consistent (sequentially consisnent memory model).
+
+            Example: declare \p %VyukovMPMCCycleQueue with item counting and static iternal buffer of size 1024:
+            \code
+            typedef cds::intrusive::VyukovMPMCCycleQueue< Foo, 
+                typename cds::intrusive::vyukov_queue::make_traits<
+                    cds::opt::buffer< cds::opt::v::static_buffer< void *, 1024 >,
+                    cds::opt::item_counte< cds::atomicity::item_counter >
+                >::type
+            > myQueue;
+            \endcode
+        */
+        template <typename... Options>
+        struct make_traits {
+#   ifdef CDS_DOXYGEN_INVOKED
+            typedef implementation_defined type;   ///< Metafunction result
+#   else
+            typedef typename cds::opt::make_options<
+                typename cds::opt::find_type_traits< traits, Options... >::type
+                , Options...
+            >::type type;
+#   endif
+        };
+
+    } // namespace vyukov_queue
+
     /// Vyukov's MPMC bounded queue
     /** @ingroup cds_intrusive_queue
         This algorithm is developed by Dmitry Vyukov (see http://www.1024cores.net)
 
-        Implementation of intrusive version is based on non-intrusive class container::VyukovMPMCCycleQueue.
+        Implementation of intrusive version is based on container::VyukovMPMCCycleQueue.
 
         Template parameters:
         - \p T - type stored in queue.
-        - \p Options - queue's options
-
-        Options \p Options are:
-        - opt::buffer - buffer to store items. Mandatory option, see option description for full list of possible types.
-        - opt::item_counter - the type of item counting feature. Default is \ref atomicity::empty_item_counter
-        - opt::disposer - the functor used for dispose removed items. Default is opt::v::empty_disposer. This option is used
-            only in \ref clear function.
-        - opt::alignment - the alignment for internal queue data. Default is opt::cache_line_alignment
-        - opt::memory_model - C++ memory ordering model. Can be opt::v::relaxed_ordering (relaxed memory model, the default)
-            or opt::v::sequential_consistent (sequentially consisnent memory model).
-
+        - \p Traits - queue traits, default is \p vykov_queue::traits. You can use \p vykov_queue::make_traits
+            metafunction to make your traits or just derive your traits from \p %vykov_queue::traits:
+            \code
+            struct myTraits: public cds::intrusive::vykov_queue::traits {
+                typedef cds::atomicity::item_counter    item_counter;
+            };
+            typedef cds::intrusive::VyukovMPMCCycleQueue< Foo, myTraits > myQueue;
+
+            // Equivalent make_traits example:
+            typedef cds::intrusive::VyukovMPMCCycleQueue< cds::gc::HP, Foo, 
+                typename cds::intrusive::vykov_queue::make_traits< 
+                    cds::opt::item_counter< cds::atomicity::item_counter >
+                >::type
+            > myQueue;
+            \endcode
 
         Instead of saving copy of enqueued data, the intrusive implementation stores pointer to passed data.
 
@@ -39,49 +91,47 @@ namespace cds { namespace intrusive {
         };
 
         // Queue of Foo pointers, capacity is 1024, statically allocated buffer:
-        typedef cds::intrusive::VyukovMPMCCycleQueue<
-            Foo
-            ,cds::opt::buffer< cds::opt::v::static_buffer< Foo, 1024 > >
+        typedef cds::intrusive::VyukovMPMCCycleQueue< Foo,
+            typename cds::intrusive::vyukov_queue::make_traits<
+                cds::opt::buffer< cds::opt::v::static_buffer< Foo, 1024 > >
+            >::type
         > static_queue;
         static_queue    stQueue;
 
         // Queue of Foo pointers, capacity is 1024, dynamically allocated buffer:
-        typedef cds::intrusive::VyukovMPMCCycleQueue<
-            Foo
-            ,cds::opt::buffer< cds::opt::v::dynamic_buffer< Foo > >
-        > dynamic_queue;
+        struct queue_traits: public cds::intrusive::vyukov_queue::traits
+        {
+            typedef cds::opt::v::dynamic_buffer< Foo > buffer;
+        };
+        typedef cds::intrusive::VyukovMPMCCycleQueue< Foo, queue_traits > dynamic_queue;
         dynamic_queue    dynQueue( 1024 );
-
         \endcode
     */
-    template <typename T, typename... Options>
+    template <typename T, typename Traits = vyukov_queue::traits >
     class VyukovMPMCCycleQueue
-        : private container::VyukovMPMCCycleQueue< T *, Options... >
+        : private container::VyukovMPMCCycleQueue< T*, Traits >
     {
         //@cond
-        typedef container::VyukovMPMCCycleQueue< T *, Options... > base_class;
+        typedef container::VyukovMPMCCycleQueue< T*, Traits > base_class;
         //@endcond
     public:
-        typedef T value_type    ;   ///< type of data stored in the queue
-        typedef typename base_class::item_counter   item_counter    ;   ///< Item counter type
-        typedef typename base_class::memory_model   memory_model    ;   ///< Memory ordering. See cds::opt::memory_model option
-        typedef typename base_class::options::disposer disposer     ;   ///< Item disposer
-
-        //@cond
-        typedef typename base_class::options    options;
-        //@endcond
+        typedef T value_type;   ///< type of data to be stored in the queue
+        typedef Traits traits;  ///< Queue traits
+        typedef typename traits::item_counter   item_counter;   ///< Item counter type
+        typedef typename traits::memory_model   memory_model;   ///< Memory ordering. See cds::opt::memory_model option
+        typedef typename traits::disposer       disposer;       ///< Item disposer
 
     public:
         /// Rebind template arguments
-        template <typename T2, typename... Options2>
+        template <typename T2, typename Traits2>
         struct rebind {
-            typedef VyukovMPMCCycleQueue< T2, Options2...> other   ;   ///< Rebinding result
+            typedef VyukovMPMCCycleQueue< T2, Traits2> other   ;   ///< Rebinding result
         };
 
     public:
         /// Constructs the queue of capacity \p nCapacity
         /**
-            For cds::opt::v::static_buffer the \p nCapacity parameter is ignored.
+            For \p cds::opt::v::static_buffer the \p nCapacity parameter is ignored.
         */
         VyukovMPMCCycleQueue( size_t nCapacity = 0 )
             : base_class( nCapacity )
@@ -89,7 +139,7 @@ namespace cds { namespace intrusive {
 
         /// Enqueues \p data to queue
         /**
-            Note that the intrusive queue stores pointer to \p data passed, not the copy of data.
+            @note The intrusive queue stores pointer to \p data passed, not the copy of \p data.
         */
         bool enqueue( value_type& data )
         {
@@ -98,6 +148,8 @@ namespace cds { namespace intrusive {
 
         /// Dequeues an item from queue
         /**
+            \p Traits::disposer is not called. You may manually delete the returned pointer.
+
             If queue is empty, returns \p nullptr.
         */
         value_type * dequeue()
@@ -106,13 +158,13 @@ namespace cds { namespace intrusive {
             return base_class::dequeue( p ) ? p : nullptr;
         }
 
-        /// Synonym of \ref enqueue
+        /// Synonym for \p enqueue()
         bool push( value_type& data )
         {
             return enqueue( data );
         }
 
-        /// Synonym of \ref dequeue
+        /// Synonym for \p dequeue()
         value_type * pop()
         {
             return dequeue();
@@ -121,7 +173,7 @@ namespace cds { namespace intrusive {
         /// Clears queue in lock-free manner.
         /**
             \p f parameter is a functor to dispose removed items.
-            The interface of \p DISPOSER is:
+            The interface of \p Disposer is:
             \code
             struct myDisposer {
                 void operator ()( T * val );
@@ -141,7 +193,7 @@ namespace cds { namespace intrusive {
 
         /// Clears the queue
         /**
-            This function uses the disposer that is specified in \p Options.
+            This function uses the disposer that is specified in \p Traits.
         */
         void clear()
         {
@@ -154,18 +206,17 @@ namespace cds { namespace intrusive {
             return base_class::empty();
         }
 
-
         /// Returns queue's item count
         /**
-            The value returned depends on opt::item_counter option. For atomicity::empty_item_counter,
-            this function always returns 0.
+            The value returned depends on \p vyukov_queue::traits::item_counter option.
+            For \p atomicity::empty_item_counter, this function always returns 0.
         */
         size_t size() const
         {
             return base_class::size();
         }
 
-        /// Returns capacity of cyclic buffer
+        /// Returns capacity of the queue
         size_t capacity() const
         {
             return base_class::capacity();
index 35f4ffaeddc3a58f7aa513cf2525a545ca284ca7..5680f17f1c8092aaa19a7dd37d9e2c57b67492f3 100644 (file)
@@ -145,14 +145,14 @@ namespace michael {
             }
         };
 #endif
-
-        typedef container::VyukovMPMCCycleQueue<
-            void *,
-            opt::buffer< opt::v::static_buffer<void *, FreeListCapacity> >
+        struct free_list_traits : public cds::container::vyukov_queue::traits
+        {
+            typedef opt::v::static_buffer<void *, FreeListCapacity> buffer;
 #ifdef _DEBUG
-            , opt::value_cleaner< make_null_ptr >
+            typedef make_null_ptr value_cleaner;
 #endif
-        >   free_list;
+        };
+        typedef container::VyukovMPMCCycleQueue< void *, free_list_traits > free_list;
 
         free_list   m_FreeList;
         //@endcond
index 4eccf9c578761f1fbe2a82380d4c1918f51861b9..f7c3ceb578a1192be0caa9336e4f18f18dac70ce 100644 (file)
@@ -8,12 +8,20 @@
 
 namespace cds { namespace memory {
 
+    /// \p vyukov_queue_pool traits
+    /** @ingroup cds_memory_pool
+    */
+    struct vyukov_queue_pool_traits : public cds::intrusive::vyukov_queue::traits
+    {
+        /// Allocator type
+        typedef CDS_DEFAULT_ALLOCATOR allocator;
+    };
     /// Free-list based on bounded lock-free queue cds::intrusive::VyukovMPMCCycleQueue
     /** @ingroup cds_memory_pool
         Template parameters:
         - \p T - the type of object maintaining by free-list
-        - \p Options - the options of cds::intrusive::VyukovMPMCCycleQueue class plus
-            cds::opt::allocator option.
+        - \p Traits - traits for cds::intrusive::VyukovMPMCCycleQueue class plus
+            cds::opt::allocator option, defaul is \p vyukov_queue_pool_traits
 
         \b Internals
 
@@ -37,7 +45,11 @@ namespace cds { namespace memory {
         #include <cds/memory/pool_allocator.h>
 
         // Pool of Foo object of size 1024.
-        typedef cds::memory::vyukov_queue_pool< Foo, cds::opt::buffer< cds::opt::v::static_buffer< Foo, 1024 > > pool_type;
+        struct pool_traits: public cds::memory::vyukov_queue_pool_traits
+        {
+            typedef cds::opt::v::static_buffer< Foo, 1024 > buffer;
+        };
+        typedef cds::memory::vyukov_queue_pool< Foo, pool_traits > pool_type;
         static pool_type thePool;
 
         struct pool_accessor {
@@ -68,24 +80,16 @@ namespace cds { namespace memory {
         pool_allocator().deallocate( p , 1 );
         \endcode
     */
-    template <typename T, typename... Options>
+    template <typename T, typename Traits = vyukov_queue_pool_traits >
     class vyukov_queue_pool
     {
     public:
-        typedef cds::intrusive::VyukovMPMCCycleQueue< T, Options... > queue_type  ;   ///< Queue type
-
-    protected:
-        //@cond
-        struct default_options: public queue_type::options
-        {
-            typedef CDS_DEFAULT_ALLOCATOR   allocator;
-        };
-        typedef typename opt::make_options< default_options, Options... >::type   options;
-        //@endcond
+        typedef cds::intrusive::VyukovMPMCCycleQueue< T, Traits > queue_type  ;   ///< Queue type
 
     public:
         typedef T  value_type ; ///< Value type
-        typedef typename options::allocator::template rebind<value_type>::other allocator_type  ;   ///< allocator type
+        typedef Traits traits;  ///< Traits type
+        typedef typename traits::allocator::template rebind<value_type>::other allocator_type  ;   ///< allocator type
 
     protected:
         //@cond
@@ -173,12 +177,13 @@ namespace cds { namespace memory {
         }
     };
 
+
     /// Lazy free-list based on bounded lock-free queue cds::intrusive::VyukovMPMCCycleQueue
     /** @ingroup cds_memory_pool
         Template parameters:
         - \p T - the type of object maintaining by free-list
-        - \p Options - the options of cds::intrusive::VyukovMPMCCycleQueue class plus
-            cds::opt::allocator option.
+        - \p Traits - traits for cds::intrusive::VyukovMPMCCycleQueue class plus
+            cds::opt::allocator option, defaul is \p vyukov_queue_pool_traits
 
         \b Internals
 
@@ -201,7 +206,7 @@ namespace cds { namespace memory {
         #include <cds/memory/pool_allocator.h>
 
         // Pool of Foo object of size 1024.
-        typedef cds::memory::lazy_vyukov_queue_pool< Foo, cds::opt::buffer< cds::opt::v::dynamic_buffer< Foo > > pool_type;
+        typedef cds::memory::lazy_vyukov_queue_pool< Foo > pool_type;
         static pool_type thePool( 1024 );
 
         struct pool_accessor {
@@ -233,24 +238,16 @@ namespace cds { namespace memory {
         \endcode
 
     */
-    template <typename T, typename... Options>
+    template <typename T, typename Traits = vyukov_queue_pool_traits>
     class lazy_vyukov_queue_pool
     {
     public:
-        typedef cds::intrusive::VyukovMPMCCycleQueue< T, Options... > queue_type  ;   ///< Queue type
-
-    protected:
-        //@cond
-        struct default_options: public queue_type::options
-        {
-            typedef CDS_DEFAULT_ALLOCATOR   allocator;
-        };
-        typedef typename opt::make_options< default_options, Options... >::type   options;
-        //@endcond
+        typedef cds::intrusive::VyukovMPMCCycleQueue< T, Traits > queue_type  ;   ///< Queue type
 
     public:
         typedef T  value_type ; ///< Value type
-        typedef typename options::allocator::template rebind<value_type>::other allocator_type  ;   ///< allocator type
+        typedef Traits traits;  ///< Pool traits
+        typedef typename traits::allocator::template rebind<value_type>::other allocator_type  ;   ///< allocator type
 
     protected:
         //@cond
@@ -316,19 +313,19 @@ namespace cds { namespace memory {
     /** @ingroup cds_memory_pool
         Template parameters:
         - \p T - the type of object maintaining by free-list
-        - \p Options - the options of cds::intrusive::VyukovMPMCCycleQueue class plus
-            cds::opt::allocator option.
+        - \p Traits - traits for cds::intrusive::VyukovMPMCCycleQueue class plus
+            cds::opt::allocator option, defaul is \p vyukov_queue_pool_traits
 
         \b Internals
 
         At construction time, the free-list allocates the array of N items
-        and stores them into queue, where N is the queue capacity.
+        and stores them into the queue, where N is the queue capacity.
         When allocating the free-list tries to pop an object from
         internal queue i.e. from preallocated pool. If success the popped object is returned.
         Otherwise a \p std::bad_alloc exception is raised.
         So, the pool can contain up to \p N items.
-        When deallocating, the object is pushed into queue.
-        In debug mode the \ref deallocate member function asserts
+        When deallocating, the object is pushed into the queue.
+        In debug mode \p deallocate() member function asserts
         that the pointer is from preallocated pool.
 
         \b Usage
@@ -341,7 +338,11 @@ namespace cds { namespace memory {
         #include <cds/memory/pool_allocator.h>
 
         // Pool of Foo object of size 1024.
-        typedef cds::memory::bounded_vyukov_queue_pool< Foo, cds::opt::buffer< cds::opt::v::static_buffer< Foo, 1024 > > pool_type;
+        struct pool_traits: public cds::memory::vyukov_queue_pool_traits
+        {
+            typedef cds::opt::v::static_buffer< Foo, 1024 > buffer;
+        };
+        typedef cds::memory::bounded_vyukov_queue_pool< Foo, pool_traits > pool_type;
         static pool_type thePool;
 
         struct pool_accessor {
@@ -372,24 +373,16 @@ namespace cds { namespace memory {
         pool_allocator().deallocate( p , 1 );
         \endcode
     */
-    template <typename T, typename... Options>
+    template <typename T, typename Traits = vyukov_queue_pool_traits >
     class bounded_vyukov_queue_pool
     {
     public:
-        typedef cds::intrusive::VyukovMPMCCycleQueue< T, Options... > queue_type  ;   ///< Queue type
-
-    protected:
-        //@cond
-        struct default_options: public queue_type::options
-        {
-            typedef CDS_DEFAULT_ALLOCATOR   allocator;
-        };
-        typedef typename opt::make_options< default_options, Options... >::type   options;
-        //@endcond
+        typedef cds::intrusive::VyukovMPMCCycleQueue< T, Traits > queue_type  ;   ///< Queue type
 
     public:
-        typedef T  value_type ; ///< Value type
-        typedef typename options::allocator::template rebind<value_type>::other allocator_type  ;   ///< allocator type
+        typedef T  value_type;  ///< Value type
+        typedef Traits traits;  ///< Pool traits
+        typedef typename traits::allocator::template rebind<value_type>::other allocator_type  ;   ///< allocator type
 
     protected:
         //@cond
index 9e8c4c63458054f29a32234a9eebec2527d3f428..9b0cbd1f48788b20f67a490d4fdc429d9c326dff 100644 (file)
@@ -39,10 +39,7 @@ namespace cds { namespace urcu {
         - \p Backoff - back-off schema, default is cds::backoff::Default
     */
     template <
-        class Buffer = cds::container::VyukovMPMCCycleQueue<
-            epoch_retired_ptr
-            ,cds::opt::buffer< cds::opt::v::dynamic_buffer< epoch_retired_ptr > >
-        >
+        class Buffer = cds::container::VyukovMPMCCycleQueue< epoch_retired_ptr >
         ,class Lock = std::mutex
         ,class Backoff = cds::backoff::Default
     >
index f7712634f58cb607ba35edc885982f5a481b2d13..8d1031d78739269c0bfaf3eaf2fe42706f10180d 100644 (file)
@@ -38,10 +38,7 @@ namespace cds { namespace urcu {
         - \p Backoff - back-off schema, default is cds::backoff::Default
     */
     template <
-        class Buffer = cds::container::VyukovMPMCCycleQueue<
-            epoch_retired_ptr
-            ,cds::opt::buffer< cds::opt::v::dynamic_buffer< epoch_retired_ptr > >
-        >
+        class Buffer = cds::container::VyukovMPMCCycleQueue< epoch_retired_ptr >
         ,class Lock = std::mutex
         ,class DisposerThread = dispose_thread<Buffer>
         ,class Backoff = cds::backoff::Default
index 13786c7d090fc6f80e3440ee4dcabb2b4e90d6d9..5737b4acb84da11743121a0156e71311651fdd22 100644 (file)
@@ -41,10 +41,7 @@ namespace cds { namespace urcu {
         - \p Backoff - back-off schema, default is cds::backoff::Default
     */
     template <
-        class Buffer = cds::container::VyukovMPMCCycleQueue<
-            epoch_retired_ptr
-            ,cds::opt::buffer< cds::opt::v::dynamic_buffer< epoch_retired_ptr > >
-        >
+        class Buffer = cds::container::VyukovMPMCCycleQueue< epoch_retired_ptr >
         ,class Lock = std::mutex
         ,class Backoff = cds::backoff::Default
     >
index 2f5db2e215edcdc8453ea8f4f781c0d2e4ff58a7..9fb2dfe979a5ff30a0ec88d24adff18d399e4aa1 100644 (file)
@@ -40,10 +40,7 @@ namespace cds { namespace urcu {
         - \p Backoff - back-off schema, default is cds::backoff::Default
     */
     template <
-        class Buffer = cds::container::VyukovMPMCCycleQueue<
-            epoch_retired_ptr
-            ,cds::opt::buffer< cds::opt::v::dynamic_buffer< epoch_retired_ptr > >
-        >
+        class Buffer = cds::container::VyukovMPMCCycleQueue< epoch_retired_ptr >
         ,class Lock = std::mutex
         ,class DisposerThread = dispose_thread<Buffer>
         ,class Backoff = cds::backoff::Default
index 4b042f0ed8bf14c5dafeb4e8de7ef3e6656f289c..b55dd2e7b31596df1b1f93cde64766efb05b4225 100644 (file)
@@ -20,10 +20,7 @@ namespace cds { namespace urcu {
     */
     template <
 #ifdef CDS_DOXGEN_INVOKED
-        class Buffer = cds::container::VyukovMPMCCycleQueue<
-            retired_ptr
-            ,cds::opt::buffer< cds::opt::v::dynamic_buffer< retired_ptr > >
-        >
+        class Buffer = cds::container::VyukovMPMCCycleQueue< retired_ptr >
         ,class Lock = std::mutex
         ,class Backoff = cds::backoff::Default
 #else
index 57699ce1ef8bd181313cbafacc99a33353b3636f..57e532207ca0879886ef5d698953a8240cc32128 100644 (file)
@@ -23,10 +23,7 @@ namespace cds { namespace urcu {
     */
     template <
 #ifdef CDS_DOXGEN_INVOKED
-        class Buffer = cds::container::VyukovMPMCCycleQueue<
-            epoch_retired_ptr
-            ,cds::opt::buffer< cds::opt::v::dynamic_buffer< epoch_retired_ptr > >
-        >
+        class Buffer = cds::container::VyukovMPMCCycleQueue< epoch_retired_ptr >
         ,class Lock = std::mutex
         ,class DisposerThread = dispose_thread<Buffer>
         ,class Backoff = cds::backoff::Default
index 0d26dfe4ecd7a50ae6dc547d7fc45e62ea6bf9eb..c62ab3f07d582d390d2618d06996c2fb64a39969 100644 (file)
@@ -21,10 +21,7 @@ namespace cds { namespace urcu {
     */
     template <
 #ifdef CDS_DOXGEN_INVOKED
-        class Buffer = cds::container::VyukovMPMCCycleQueue<
-            retired_ptr
-            ,cds::opt::buffer< cds::opt::v::dynamic_buffer< retired_ptr > >
-        >
+        class Buffer = cds::container::VyukovMPMCCycleQueue< retired_ptr >
         ,class Lock = std::mutex
         ,class Backoff = cds::backoff::Default
 #else
index e8546b01653fadf99fea580d751dc77f1e95936c..3d4971dbb2514a02efb16910404daea06631734d 100644 (file)
@@ -25,10 +25,7 @@ namespace cds { namespace urcu {
     */
     template <
 #ifdef CDS_DOXGEN_INVOKED
-        class Buffer = cds::container::VyukovMPMCCycleQueue<
-            epoch_retired_ptr
-            ,cds::opt::buffer< cds::opt::v::dynamic_buffer< epoch_retired_ptr > >
-        >
+        class Buffer = cds::container::VyukovMPMCCycleQueue< epoch_retired_ptr >
         ,class Lock = std::mutex
         ,class DisposerThread = dispose_thread<Buffer>
         ,class Backoff = cds::backoff::Default
index 8ef8984e35b4504d38e5670aba85a092aee15cb0..61624b653f17057a9de6d5d219bbc1483af2ac77 100644 (file)
@@ -385,8 +385,8 @@ namespace queue {
         void test_TsigasCycleQueue_dyn();
         void test_TsigasCycleQueue_dyn_ic();
 
-        void test_VyukovMPMCCycleQueue_stat();
-        void test_VyukovMPMCCycleQueue_stat_ic();
+        void test_VyukovMPMCCycleQueue_static();
+        void test_VyukovMPMCCycleQueue_static_ic();
         void test_VyukovMPMCCycleQueue_dyn();
         void test_VyukovMPMCCycleQueue_dyn_ic();
 
@@ -508,8 +508,8 @@ namespace queue {
             CPPUNIT_TEST(test_TsigasCycleQueue_dyn)
             CPPUNIT_TEST(test_TsigasCycleQueue_dyn_ic)
 
-            CPPUNIT_TEST(test_VyukovMPMCCycleQueue_stat);
-            CPPUNIT_TEST(test_VyukovMPMCCycleQueue_stat_ic);
+            CPPUNIT_TEST(test_VyukovMPMCCycleQueue_static);
+            CPPUNIT_TEST(test_VyukovMPMCCycleQueue_static_ic);
             CPPUNIT_TEST(test_VyukovMPMCCycleQueue_dyn);
             CPPUNIT_TEST(test_VyukovMPMCCycleQueue_dyn_ic);
 
index e46dc85c6e34d8cb1f369e7235f66f9da3e1a3ad..f0a36236cba91e5b0b7b41a4ac8e8583ff2f8352 100644 (file)
@@ -17,53 +17,47 @@ namespace queue {
             {}
         };
 
-        typedef ci::VyukovMPMCCycleQueue<
-            item
-            ,co::buffer< co::v::static_buffer< int, 1024 > >
-            ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
-            ,co::memory_model< co::v::sequential_consistent >
-        > VyukovMPMCCycleQueue_stat;
+        struct traits_VyukovMPMCCycleQueue_static : public ci::vyukov_queue::traits
+        {
+            typedef co::v::static_buffer< int, 1024 > buffer;
+            typedef IntrusiveQueueHeaderTest::faked_disposer disposer;
+            typedef co::v::sequential_consistent memory_model;
+        };
+        typedef ci::VyukovMPMCCycleQueue< item, traits_VyukovMPMCCycleQueue_static > VyukovMPMCCycleQueue_static;
 
-        typedef ci::VyukovMPMCCycleQueue<
-            item
-            ,co::buffer< co::v::static_buffer< int, 1024 > >
-            ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
-            ,co::item_counter< cds::atomicity::item_counter >
-            ,co::memory_model< co::v::relaxed_ordering >
-        > VyukovMPMCCycleQueue_stat_ic;
+        struct traits_VyukovMPMCCycleQueue_static_ic : public traits_VyukovMPMCCycleQueue_static
+        {
+            typedef cds::atomicity::item_counter item_counter;
+        };
+        typedef ci::VyukovMPMCCycleQueue< item, traits_VyukovMPMCCycleQueue_static_ic > VyukovMPMCCycleQueue_static_ic;
 
+        struct traits_VyukovMPMCCycleQueue_dyn :
+            public ci::vyukov_queue::make_traits <
+                co::buffer< co::v::dynamic_buffer< int > >,
+                ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+            >::type
+        {};
         class VyukovMPMCCycleQueue_dyn
-            : public ci::VyukovMPMCCycleQueue<
-                item
-                ,co::buffer< co::v::dynamic_buffer< int > >
-                ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
-            >
+            : public ci::VyukovMPMCCycleQueue< item, traits_VyukovMPMCCycleQueue_dyn >
         {
-            typedef ci::VyukovMPMCCycleQueue<
-                item
-                ,co::buffer< co::v::dynamic_buffer< int > >
-                ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
-            > base_class;
+            typedef ci::VyukovMPMCCycleQueue< item, traits_VyukovMPMCCycleQueue_dyn > base_class;
+
         public:
             VyukovMPMCCycleQueue_dyn()
                 : base_class( 1024 )
             {}
         };
 
+        struct traits_VyukovMPMCCycleQueue_dyn_ic :
+            public ci::vyukov_queue::make_traits <
+                ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+                , co::item_counter< cds::atomicity::item_counter >
+            >::type
+        {};
         class VyukovMPMCCycleQueue_dyn_ic
-            : public ci::VyukovMPMCCycleQueue<
-                item
-                ,co::buffer< co::v::dynamic_buffer< int > >
-                ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
-                ,co::item_counter< cds::atomicity::item_counter >
-            >
+            : public ci::VyukovMPMCCycleQueue< item, traits_VyukovMPMCCycleQueue_dyn_ic >
         {
-            typedef ci::VyukovMPMCCycleQueue<
-                item
-                ,co::buffer< co::v::dynamic_buffer< int > >
-                ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
-                ,co::item_counter< cds::atomicity::item_counter >
-            > base_class;
+            typedef ci::VyukovMPMCCycleQueue< item, traits_VyukovMPMCCycleQueue_dyn_ic > base_class;
         public:
             VyukovMPMCCycleQueue_dyn_ic()
                 : base_class( 1024 )
@@ -71,8 +65,8 @@ namespace queue {
         };
     }
 
-    TEST(VyukovMPMCCycleQueue_stat)
-    TEST(VyukovMPMCCycleQueue_stat_ic)
+    TEST(VyukovMPMCCycleQueue_static)
+    TEST(VyukovMPMCCycleQueue_static_ic)
     TEST(VyukovMPMCCycleQueue_dyn)
     TEST(VyukovMPMCCycleQueue_dyn_ic)
 
index f213e771b6893afbf29053c83ab76ecc910a9611..c7c0c9a8019d5703a78ad90f385090be58a7a4b1 100644 (file)
@@ -148,9 +148,6 @@ namespace queue {
         void FCQueue_list_mutex();
         void FCQueue_list_stat();
 
-        void Vyukov_MPMCCyclicQueue();
-        void Vyukov_MPMCCyclicQueue_Counted();
-
         CPPUNIT_TEST_SUITE(Queue_TestHeader)
             CPPUNIT_TEST(FCQueue_deque)
             CPPUNIT_TEST(FCQueue_deque_elimination)
@@ -160,9 +157,6 @@ namespace queue {
             CPPUNIT_TEST(FCQueue_list_elimination)
             CPPUNIT_TEST(FCQueue_list_mutex)
             CPPUNIT_TEST(FCQueue_list_stat)
-
-            CPPUNIT_TEST(Vyukov_MPMCCyclicQueue);
-            CPPUNIT_TEST(Vyukov_MPMCCyclicQueue_Counted);
         CPPUNIT_TEST_SUITE_END();
 
     };
index f82fda6cfe2dba6d8b651322a42ffdad601a2be1..35cfa0c3c1e675ef9bdc83a1de75c5d74f416e54 100644 (file)
@@ -345,10 +345,10 @@ namespace queue {
         void TsigasCycleQueue_dyn();
         void TsigasCycleQueue_dyn_ic();
 
-        /*
-        void Vyukov_MPMCCyclicQueue();
-        void Vyukov_MPMCCyclicQueue_Counted();
-        */
+        void VyukovMPMCCycleQueue_static();
+        void VyukovMPMCCycleQueue_static_ic();
+        void VyukovMPMCCycleQueue_dyn();
+        void VyukovMPMCCycleQueue_dyn_ic();
 
         CPPUNIT_TEST_SUITE( HdrTestQueue )
             CPPUNIT_TEST(MSQueue_HP);
@@ -444,10 +444,11 @@ namespace queue {
             CPPUNIT_TEST( TsigasCycleQueue_dyn )
             CPPUNIT_TEST( TsigasCycleQueue_dyn_ic )
 
-/*
-            CPPUNIT_TEST(Vyukov_MPMCCyclicQueue);
-            CPPUNIT_TEST(Vyukov_MPMCCyclicQueue_Counted);
-*/
+            CPPUNIT_TEST( VyukovMPMCCycleQueue_static )
+            CPPUNIT_TEST( VyukovMPMCCycleQueue_static_ic )
+            CPPUNIT_TEST( VyukovMPMCCycleQueue_dyn )
+            CPPUNIT_TEST( VyukovMPMCCycleQueue_dyn_ic )
+
             CPPUNIT_TEST( RWQueue_default)
             CPPUNIT_TEST( RWQueue_mutex )
             CPPUNIT_TEST( RWQueue_ic )
index 787aa51f5957fb3c4eba5de07fe864a8d2646494..2b0b38bec9379749cdfcd4851e93f6371dc2fea6 100644 (file)
@@ -53,7 +53,7 @@ namespace queue {
     {
         class queue_type
             : public cds::container::TsigasCycleQueue< int,
-            typename cds::container::tsigas_queue::make_traits<
+                typename cds::container::tsigas_queue::make_traits<
                     cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
                     , cds::opt::item_counter< cds::atomicity::item_counter >
                 >::type
index cd26d9e9274d7ab040594d57bce21014a649d7da..606ef43efd0f850d7943ab5148fcdd128db9134d 100644 (file)
@@ -2,52 +2,45 @@
 
 #include <cds/container/vyukov_mpmc_cycle_queue.h>
 
-#include "queue/hdr_queue.h"
+#include "queue/hdr_queue_new.h"
 
 namespace queue {
-    namespace {
-        class VyukovMPMCCyclicQueue_int:
-            public cds::container::VyukovMPMCCycleQueue<
-                int,
-                cds::opt::buffer<cds::opt::v::static_buffer<int, 1024 *32 > >
-            >
+    namespace{
+        struct traits_VyukovMPMCCyclicQueue_static : public cds::container::vyukov_queue::traits
         {
-            typedef cds::container::VyukovMPMCCycleQueue<
-                int,
-                cds::opt::buffer<cds::opt::v::static_buffer<int, 1024 *32 > >
-            > base_class;
-        public:
-            VyukovMPMCCyclicQueue_int()
-                : base_class(1024 * 32)
-            {}
+            typedef cds::opt::v::static_buffer<int, 1024> buffer;
         };
-
-        class VyukovMPMCCyclicQueue_int_ic:
-            public cds::container::VyukovMPMCCycleQueue<
-                int,
-                cds::opt::buffer<cds::opt::v::dynamic_buffer<int> >,
-                cds::opt::item_counter< cds::atomicity::item_counter >
-            >
+        struct traits_VyukovMPMCCyclicQueue_static_ic : public traits_VyukovMPMCCyclicQueue_static
         {
-            typedef cds::container::VyukovMPMCCycleQueue<
-                int,
-                cds::opt::buffer<cds::opt::v::dynamic_buffer<int> >,
-                cds::opt::item_counter< cds::atomicity::item_counter >
-            > base_class;
-        public:
-            VyukovMPMCCyclicQueue_int_ic()
-                : base_class( 32 * 1024 )
-            {}
+            typedef cds::atomicity::item_counter item_counter;
         };
     }
+    void HdrTestQueue::VyukovMPMCCycleQueue_static()
+    {
+        typedef cds::container::VyukovMPMCCycleQueue< int, traits_VyukovMPMCCyclicQueue_static > queue_type;
+
+        test_bounded_no_ic< queue_type >();
+    }
 
-    void Queue_TestHeader::Vyukov_MPMCCyclicQueue()
+    void HdrTestQueue::VyukovMPMCCycleQueue_static_ic()
     {
-        testNoItemCounter< VyukovMPMCCyclicQueue_int >();
+        typedef cds::container::VyukovMPMCCycleQueue< int, traits_VyukovMPMCCyclicQueue_static_ic > queue_type;
+        test_bounded_ic< queue_type >();
     }
 
-    void Queue_TestHeader::Vyukov_MPMCCyclicQueue_Counted()
+    void HdrTestQueue::VyukovMPMCCycleQueue_dyn()
     {
-        testWithItemCounter< VyukovMPMCCyclicQueue_int_ic >();
+        test_bounded_no_ic< cds::container::VyukovMPMCCycleQueue< int > >();
     }
+
+    void HdrTestQueue::VyukovMPMCCycleQueue_dyn_ic()
+    {
+        typedef cds::container::VyukovMPMCCycleQueue < int,
+            typename cds::container::vyukov_queue::make_traits <
+                cds::opt::item_counter < cds::atomicity::item_counter >
+            > ::type
+        > queue_type;
+        test_bounded_ic< queue_type >();
+    }
+
 }
index f69fb67b87bcb807eaa276818129587ed9c84287..f18a0689d476e3218b6a8e4bcf1be0c72a1f5701 100644 (file)
@@ -18,13 +18,12 @@ namespace tree {
         typedef node_types::internal_node_type                              internal_node;
         typedef node_types::update_desc_type                                update_desc;
 
-
         // Internal node pool based on Vyukov's queue
-        typedef cds::memory::lazy_vyukov_queue_pool<
-            internal_node,
-            cds::opt::buffer< cds::opt::v::dynamic_buffer< cds::any_type > >
-        > internal_node_pool_type;
-
+        struct internal_node_pool_traits : public cds::memory::vyukov_queue_pool_traits
+        {
+            typedef cds::opt::v::dynamic_buffer< cds::any_type > buffer;
+        };
+        typedef cds::memory::lazy_vyukov_queue_pool< internal_node, internal_node_pool_traits > internal_node_pool_type;
         extern internal_node_pool_type s_InternalNodePool;
 
         struct internal_node_pool_accessor {
@@ -37,11 +36,11 @@ namespace tree {
         };
 
         // Update descriptor pool based on Vyukov's queue
-        typedef cds::memory::vyukov_queue_pool<
-            update_desc,
-            cds::opt::buffer< cds::opt::v::static_buffer< cds::any_type, 16 > >
-        > update_desc_pool_type;
-
+        struct update_desc_pool_traits : public cds::memory::vyukov_queue_pool_traits
+        {
+            typedef cds::opt::v::static_buffer< cds::any_type, 16 > buffer;
+        };
+        typedef cds::memory::vyukov_queue_pool< update_desc, update_desc_pool_traits > update_desc_pool_type;
         extern update_desc_pool_type s_UpdateDescPool;
 
         struct update_desc_pool_accessor {
index 00fd22af37b7e3dc20c70377814803e8f86c0ad5..05d2e9f6186029baf53e166d0edb1cddc52573a1 100644 (file)
@@ -20,11 +20,11 @@ namespace tree {
 
 
         // Internal node pool based on Vyukov's queue
-        typedef cds::memory::lazy_vyukov_queue_pool<
-            internal_node,
-            cds::opt::buffer< cds::opt::v::dynamic_buffer< cds::any_type > >
-        > internal_node_pool_type;
-
+        struct internal_node_pool_traits : public cds::memory::vyukov_queue_pool_traits
+        {
+            typedef cds::opt::v::dynamic_buffer< cds::any_type > buffer;
+        };
+        typedef cds::memory::lazy_vyukov_queue_pool< internal_node, internal_node_pool_traits > internal_node_pool_type;
         extern internal_node_pool_type s_InternalNodePool;
 
         struct internal_node_pool_accessor {
@@ -37,11 +37,11 @@ namespace tree {
         };
 
         // Update descriptor pool based on Vyukov's queue
-        typedef cds::memory::vyukov_queue_pool<
-            update_desc,
-            cds::opt::buffer< cds::opt::v::static_buffer< cds::any_type, 16 > >
-        > update_desc_pool_type;
-
+        struct update_desc_pool_traits : public cds::memory::vyukov_queue_pool_traits
+        {
+            typedef cds::opt::v::static_buffer< cds::any_type, 16 > buffer;
+        };
+        typedef cds::memory::vyukov_queue_pool< update_desc, update_desc_pool_traits > update_desc_pool_type;
         extern update_desc_pool_type s_UpdateDescPool;
 
         struct update_desc_pool_accessor {
index 32322752b65121cc912f6c681b5f9711042a5617..ee2cf6278208c1491e2c2f290d9983a825966026 100644 (file)
@@ -21,20 +21,13 @@ namespace tree {
         typedef node_types::internal_node_type                              internal_node;
         typedef node_types::update_desc_type                                update_desc;
 
-        /*
-        typedef cds::intrusive::ellen_bintree::node<rcu_type>               leaf_node;
-        typedef IntrusiveBinTreeHdrTest::base_hook_value< leaf_node >       base_value;
-        typedef cds::intrusive::ellen_bintree::internal_node< IntrusiveBinTreeHdrTest::key_type, leaf_node > internal_node;
-        typedef cds::intrusive::ellen_bintree::update_desc< leaf_node, internal_node >   update_desc;
-        */
-
 
         // Internal node pool based on Vyukov's queue
-        typedef cds::memory::lazy_vyukov_queue_pool<
-            internal_node,
-            cds::opt::buffer< cds::opt::v::dynamic_buffer< cds::any_type > >
-        > internal_node_pool_type;
-
+        struct internal_node_pool_traits : public cds::memory::vyukov_queue_pool_traits
+        {
+            typedef cds::opt::v::dynamic_buffer< cds::any_type > buffer;
+        };
+        typedef cds::memory::lazy_vyukov_queue_pool< internal_node, internal_node_pool_traits > internal_node_pool_type;
         extern internal_node_pool_type s_InternalNodePool;
 
         struct internal_node_pool_accessor {
@@ -47,11 +40,11 @@ namespace tree {
         };
 
         // Update descriptor pool based on Vyukov's queue
-        typedef cds::memory::vyukov_queue_pool<
-            update_desc,
-            cds::opt::buffer< cds::opt::v::static_buffer< cds::any_type, 16 > >
-        > update_desc_pool_type;
-
+        struct update_desc_pool_traits : public cds::memory::vyukov_queue_pool_traits
+        {
+            typedef cds::opt::v::static_buffer< cds::any_type, 16 > buffer;
+        };
+        typedef cds::memory::vyukov_queue_pool< update_desc, update_desc_pool_traits > update_desc_pool_type;
         extern update_desc_pool_type s_UpdateDescPool;
 
         struct update_desc_pool_accessor {
index 0887b2f915fe490e33638f461d7cef992a749f8e..cb599f4b51c4fab2ad93035e2fd1412ed7d88de7 100644 (file)
@@ -9,17 +9,18 @@
 #include <cds/memory/pool_allocator.h>
 
 namespace ellen_bintree_pool {
-    typedef cds::container::ellen_bintree::node_types< cds::urcu::gc< cds::urcu::general_instant<> >, int > node_types ; // fake
+    typedef cds::container::ellen_bintree::node_types< cds::urcu::gc< cds::urcu::general_instant<> >, int > node_types; // fake
     typedef node_types::leaf_node_type     leaf_node;
     typedef node_types::internal_node_type internal_node;
     typedef node_types::update_desc_type   update_desc;
 
     // Update descriptor pool based on Vyukov's queue
-    typedef cds::memory::vyukov_queue_pool<
-        update_desc,
-        cds::opt::buffer< cds::opt::v::static_buffer< cds::any_type, 4096 > >
-    > update_desc_pool_type;
+    struct update_desc_pool_traits : public cds::memory::vyukov_queue_pool_traits
+    {
+        typedef cds::opt::v::static_buffer< cds::any_type, 4096 > buffer;
+    };
 
+    typedef cds::memory::vyukov_queue_pool< update_desc, update_desc_pool_traits > update_desc_pool_type;
     extern update_desc_pool_type s_UpdateDescPool;
 
     struct update_desc_pool_accessor {
@@ -32,11 +33,11 @@ namespace ellen_bintree_pool {
     };
 
     // Update descriptor pool based on bounded Vyukov's queue
-    typedef cds::memory::bounded_vyukov_queue_pool<
-        update_desc,
-        cds::opt::buffer< cds::opt::v::static_buffer< cds::any_type, 4096 > >
-    > bounded_update_desc_pool_type;
-
+    struct bounded_update_desc_pool_traits : public cds::memory::vyukov_queue_pool_traits
+    {
+        typedef cds::opt::v::static_buffer< cds::any_type, 4096 > buffer;
+    };
+    typedef cds::memory::bounded_vyukov_queue_pool< update_desc, bounded_update_desc_pool_traits > bounded_update_desc_pool_type;
     extern bounded_update_desc_pool_type s_BoundedUpdateDescPool;
 
     struct bounded_update_desc_pool_accessor {
index d941f50e568af9bea2c1f3a408ce0d57d1926e11..6733439677f8c65727b591fc3049a7850d0ec4a4 100644 (file)
@@ -271,18 +271,14 @@ namespace queue {
         };
 
         // VyukovMPMCCycleQueue
+        struct traits_VyukovMPMCCycleQueue_dyn : public cds::intrusive::vyukov_queue::traits
+        {
+            typedef cds::opt::v::dynamic_buffer< int > buffer;
+        };
         class VyukovMPMCCycleQueue_dyn
-            : public cds::intrusive::VyukovMPMCCycleQueue< T,
-                typename cds::intrusive::tsigas_queue::make_traits<
-                    cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
-                >::type
-            >
+            : public cds::intrusive::VyukovMPMCCycleQueue< T, traits_VyukovMPMCCycleQueue_dyn >
         {
-            typedef cds::intrusive::VyukovMPMCCycleQueue< T,
-                typename cds::intrusive::tsigas_queue::make_traits<
-                    cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
-                >::type
-            > base_class;
+            typedef cds::intrusive::VyukovMPMCCycleQueue< T, traits_VyukovMPMCCycleQueue_dyn > base_class;
         public:
             VyukovMPMCCycleQueue_dyn()
                 : base_class( 1024 * 64 )
@@ -297,20 +293,14 @@ namespace queue {
             }
         };
 
+        struct traits_VyukovMPMCCycleQueue_dyn_ic : public traits_VyukovMPMCCycleQueue_dyn
+        {
+            typedef cds::atomicity::item_counter item_counter;
+        };
         class VyukovMPMCCycleQueue_dyn_ic
-            : public cds::intrusive::VyukovMPMCCycleQueue< T,
-                typename cds::intrusive::tsigas_queue::make_traits<
-                    cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
-                    ,cds::opt::item_counter< cds::atomicity::item_counter >
-                >::type
-            >
+            : public cds::intrusive::VyukovMPMCCycleQueue< T, traits_VyukovMPMCCycleQueue_dyn_ic >
         {
-            typedef cds::intrusive::VyukovMPMCCycleQueue< T,
-                typename cds::intrusive::tsigas_queue::make_traits<
-                    cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
-                    ,cds::opt::item_counter< cds::atomicity::item_counter >
-                >::type
-            > base_class;
+            typedef cds::intrusive::VyukovMPMCCycleQueue< T, traits_VyukovMPMCCycleQueue_dyn_ic > base_class;
         public:
             VyukovMPMCCycleQueue_dyn_ic()
                 : base_class( 1024 * 64 )
index 1a7066ed2ff87f54f24dc39553cee59ff484d90b..217a6bf4f38cd77803e47795f5ff6d0c6dec806c 100644 (file)
@@ -268,16 +268,14 @@ namespace queue {
         };
 
         // VyukovMPMCCycleQueue
+        struct traits_VyukovMPMCCycleQueue_dyn : public cds::container::vyukov_queue::traits
+        {
+            typedef cds::opt::v::dynamic_buffer< int > buffer;
+        };
         class VyukovMPMCCycleQueue_dyn
-            : public cds::container::VyukovMPMCCycleQueue<
-                Value
-                ,cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
-            >
+            : public cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn >
         {
-            typedef cds::container::VyukovMPMCCycleQueue<
-                Value
-                ,cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
-            > base_class;
+            typedef cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn > base_class;
         public:
             VyukovMPMCCycleQueue_dyn()
                 : base_class( 1024 * 64 )
@@ -292,16 +290,14 @@ namespace queue {
             }
         };
 
+        struct traits_VyukovMPMCCycleQueue_dyn_michaelAlloc : public cds::container::vyukov_queue::traits
+        {
+            typedef cds::opt::v::dynamic_buffer< int, memory::MichaelAllocator<int> > buffer;
+        };
         class VyukovMPMCCycleQueue_dyn_michaelAlloc
-            : public cds::container::VyukovMPMCCycleQueue<
-            Value
-            ,cds::opt::buffer< cds::opt::v::dynamic_buffer< int, memory::MichaelAllocator<int> > >
-            >
+            : public cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn_michaelAlloc >
         {
-            typedef cds::container::VyukovMPMCCycleQueue<
-                Value
-                ,cds::opt::buffer< cds::opt::v::dynamic_buffer< int, memory::MichaelAllocator<int> > >
-            > base_class;
+            typedef cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn_michaelAlloc > base_class;
         public:
             VyukovMPMCCycleQueue_dyn_michaelAlloc()
                 : base_class( 1024 * 64 )
@@ -316,18 +312,14 @@ namespace queue {
             }
         };
 
+        struct traits_VyukovMPMCCycleQueue_dyn_ic : public traits_VyukovMPMCCycleQueue_dyn
+        {
+            typedef cds::atomicity::item_counter item_counter;
+        };
         class VyukovMPMCCycleQueue_dyn_ic
-            : public cds::container::VyukovMPMCCycleQueue<
-                Value
-                ,cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
-                ,cds::opt::item_counter< cds::atomicity::item_counter >
-            >
+            : public cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn_ic >
         {
-            typedef cds::container::VyukovMPMCCycleQueue<
-                Value
-                ,cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
-                ,cds::opt::item_counter< cds::atomicity::item_counter >
-            > base_class;
+            typedef cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn_ic > base_class;
         public:
             VyukovMPMCCycleQueue_dyn_ic()
                 : base_class( 1024 * 64 )