From: khizmax Date: Tue, 7 Oct 2014 15:55:56 +0000 (+0400) Subject: BasketQueue refactoring X-Git-Tag: v2.0.0~222 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=6c34c452085307ec9f8ae52dc7b773af4bc3aa99;p=libcds.git BasketQueue refactoring --- diff --git a/cds/container/basket_queue.h b/cds/container/basket_queue.h index db3604a8..c3cda2a7 100644 --- a/cds/container/basket_queue.h +++ b/cds/container/basket_queue.h @@ -4,34 +4,99 @@ #define __CDS_CONTAINER_BASKET_QUEUE_H #include -#include // ref #include #include -#include +//#include namespace cds { namespace container { + /// BasketQueue related definitions + /** @ingroup cds_nonintrusive_helper + */ + namespace basket_queue { + + /// Internal statistics + template ::counter_type > + using stat = cds::intrusive::basket_queue::stat< Counter >; + + /// Dummy internal statistics + typedef cds::intrusive::basket_queue::empty_stat empty_stat; + + /// BasketQueue default type traits + struct traits + { + /// Node allocator + typedef CDS_DEFAULT_ALLOCATOR allocator; + + /// Back-off strategy + typedef cds::backoff::empty back_off; + + /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter to enable item counting + typedef atomicity::empty_item_counter item_counter; + + /// Internal statistics (by default, disabled) + /** + Possible option value are: \p basket_queue::stat, \p basket_queue::empty_stat (the default), + user-provided class that supports \p %basket_queue::stat interface. + */ + typedef basket_queue::empty_stat stat; + + /// 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 of internal queue data. Default is \p opt::cache_line_alignment + enum { alignment = opt::cache_line_alignment }; + }; + + /// Metafunction converting option list to \p basket_queue::traits + /** + Supported \p Options are: + - opt::allocator - allocator (like \p std::allocator) used for allocating queue nodes. Default is \ref CDS_DEFAULT_ALLOCATOR + - opt::back_off - back-off strategy used, default is \p cds::backoff::empty. + - 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 + - opt::stat - the type to gather internal statistics. + Possible statistics types are: \p basket_queue::stat, \p basket_queue::empty_stat, user-provided class that supports \p %basket_queue::stat interface. + Default is \p %basket_queue::empty_stat. + - opt::alignment - the alignment for internal queue data. Default is \p opt::cache_line_alignment + - 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 %BasketQueue with item counting and internal statistics + \code + typedef cds::container::BasketQueue< cds::gc::HP, Foo, + typename cds::container::basket_queue::make_traits< + cds::opt::item_counte< cds::atomicity::item_counter >, + cds::opt::stat< cds::intrusive::basket_queue::stat<> > + >::type + > myQueue; + \endcode + */ + template + 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 basket_queue + //@cond namespace details { - template + template struct make_basket_queue { typedef GC gc; typedef T value_type; - - struct default_options { - typedef cds::backoff::empty back_off; - typedef CDS_DEFAULT_ALLOCATOR allocator; - typedef atomicity::empty_item_counter item_counter; - typedef intrusive::basket_queue::dummy_stat stat; - typedef opt::v::relaxed_ordering memory_model; - enum { alignment = opt::cache_line_alignment }; - }; - - typedef typename opt::make_options< - typename cds::opt::find_type_traits< default_options, Options... >::type - ,Options... - >::type options; + typedef Traits traits; struct node_type: public intrusive::basket_queue::node< gc > { @@ -46,7 +111,7 @@ namespace cds { namespace container { {} }; - typedef typename options::allocator::template rebind::other allocator_type; + typedef typename traits::allocator::template rebind::other allocator_type; typedef cds::details::Allocator< node_type, allocator_type > cxx_allocator; struct node_deallocator @@ -57,18 +122,13 @@ namespace cds { namespace container { } }; - typedef intrusive::BasketQueue< gc, - node_type - ,intrusive::opt::hook< - intrusive::basket_queue::base_hook< opt::gc > - > - ,opt::back_off< typename options::back_off > - ,intrusive::opt::disposer< node_deallocator > - ,opt::item_counter< typename options::item_counter > - ,opt::stat< typename options::stat > - ,opt::alignment< options::alignment > - ,opt::memory_model< typename options::memory_model > - > type; + struct intrusive_traits : public traits + { + typedef intrusive::basket_queue::base_hook< opt::gc > hook; + typedef node_deallocator disposer; + }; + + typedef cds::intrusive::BasketQueue< gc, node_type, intrusive_traits > type; }; } //@endcond @@ -120,61 +180,64 @@ namespace cds { namespace container { Template arguments: - - \p GC - garbage collector type: gc::HP, gc::HRC, gc::PTB - - \p T is a type stored in the queue. It should be default-constructible, copy-constructible, assignable type. - - \p Options - options - - Permissible \p Options: - - opt::allocator - allocator (like \p std::allocator). Default is \ref CDS_DEFAULT_ALLOCATOR - - opt::back_off - back-off strategy used. If the option is not specified, the cds::backoff::empty is used - - opt::item_counter - the type of item counting feature. Default is \ref atomicity::empty_item_counter - - opt::stat - the type to gather internal statistics for debugging and profiling purposes. - Possible option value are: intrusive::basket_queue::stat, intrusive::basket_queue::dummy_stat (the default), - user-provided class that supports intrusive::basket_queue::stat interface. - Generic option intrusive::queue_stat and intrusive::queue_dummy_stat are acceptable too, however, - they will be automatically converted to intrusive::basket_queue::stat and intrusive::basket_queue::dummy_stat - respectively. - - 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 GC - garbage collector type: \p gc::HP, \p gc::DHP + - \p T - type of value to be stored in the queue + - \p Traits - queue traits, default is \p basket_queue::traits. You can use \p basket_queue::make_traits + metafunction to make your traits or just derive your traits from \p %basket_queue::traits: + \code + struct myTraits: public cds::container::basket_queue::traits { + typedef cds::intrusive::basket_queue::stat<> stat; + typedef cds::atomicity::item_counter item_counter; + }; + typedef cds::container::BasketQueue< cds::gc::HP, Foo, myTraits > myQueue; + + // Equivalent make_traits example: + typedef cds::container::BasketQueue< cds::gc::HP, Foo, + typename cds::container::basket_queue::make_traits< + cds::opt::stat< cds::container::basket_queue::stat<> >, + cds::opt::item_counter< cds::atomicity::item_counter > + >::type + > myQueue; + \endcode */ - template + template class BasketQueue: #ifdef CDS_DOXYGEN_INVOKED - intrusive::BasketQueue< GC, intrusive::basket_queue::node< T >, Options... > + private intrusive::BasketQueue< GC, intrusive::basket_queue::node< T >, Traits > #else - details::make_basket_queue< GC, T, Options... >::type + protected details::make_basket_queue< GC, T, Traits >::type #endif { //@cond - typedef details::make_basket_queue< GC, T, Options... > options; - typedef typename options::type base_class; + typedef details::make_basket_queue< GC, T, Options... > maker; + typedef typename maker::type base_class; //@endcond public: /// Rebind template arguments - template + template struct rebind { - typedef BasketQueue< GC2, T2, Options2...> other ; ///< Rebinding result + typedef BasketQueue< GC2, T2, Traits2> other ; ///< Rebinding result }; public: - typedef T value_type ; ///< Value type stored in the queue + typedef GC gc; ///< Garbage collector + typedef T value_type; ///< Type of value to be stored in the queue + typedef Traits traits; ///< Queue's traits - typedef typename base_class::gc gc ; ///< Garbage collector used - typedef typename base_class::back_off back_off ; ///< Back-off strategy used - typedef typename options::allocator_type allocator_type ; ///< Allocator type used for allocate/deallocate the nodes - typedef typename base_class::item_counter item_counter ; ///< Item counting policy used - typedef typename base_class::stat stat ; ///< Internal statistics policy used - typedef typename base_class::memory_model memory_model ; ///< Memory ordering. See cds::opt::memory_model option + typedef typename base_class::back_off back_off; ///< Back-off strategy used + typedef typename maker::allocator_type allocator_type; ///< Allocator type used for allocate/deallocate the nodes + typedef typename base_class::item_counter item_counter; ///< Item counting policy used + typedef typename base_class::stat stat; ///< Internal statistics policy used + typedef typename base_class::memory_model memory_model; ///< Memory ordering. See cds::opt::memory_model option protected: - typedef typename options::node_type node_type ; ///< queue node type (derived from intrusive::single_link::node) + typedef typename maker::node_type node_type; ///< queue node type (derived from intrusive::basket_queue::node) //@cond - typedef typename options::cxx_allocator cxx_allocator; - typedef typename options::node_deallocator node_deallocator; // deallocate node - typedef typename base_class::node_traits node_traits; + typedef typename maker::cxx_allocator cxx_allocator; + typedef typename maker::node_deallocator node_deallocator; // deallocate node + typedef typename base_class::node_traits node_traits; //@endcond protected: @@ -203,7 +266,7 @@ namespace cds { namespace container { free_node( pNode ); } }; - typedef std::unique_ptr< node_type, node_disposer > scoped_node_ptr; + typedef std::unique_ptr< node_type, node_disposer > scoped_node_ptr; //@endcond public: @@ -215,27 +278,13 @@ namespace cds { namespace container { ~BasketQueue() {} - /// Returns queue's item count - /** \copydetails cds::intrusive::BasketQueue::size() - */ - size_t size() const - { - return base_class::size(); - } - - /// Returns reference to internal statistics - const stat& statistics() const - { - return base_class::statistics(); - } - /// Enqueues \p val value into the queue. /** The function makes queue node in dynamic memory calling copy constructor for \p val - and then it calls intrusive::BasketQueue::enqueue. + and then it calls \p intrusive::BasketQueue::enqueue(). Returns \p true if success, \p false otherwise. */ - bool enqueue( const value_type& val ) + bool enqueue( value_type const& val ) { scoped_node_ptr p( alloc_node(val)); if ( base_class::enqueue( *p )) { @@ -245,29 +294,21 @@ namespace cds { namespace container { return false; } - /// Enqueues \p data to queue using copy functor + /// Enqueues \p data to queue using a functor /** - \p Func is a functor called to copy value \p data of type \p Type - which may be differ from type \p T stored in the queue. - The functor's interface is: + \p Func is a functor called to create node. + The functor \p f takes one argument - a reference to a new node of type \ref value_type : \code - struct myFunctor { - void operator()(T& dest, Type const& data) - { - // // Code to copy \p data to \p dest - dest = data; - } - }; + cds::container::BasketQueue< cds::gc::HP, Foo > myQueue; + Bar bar; + myQueue.enqueue_with( [&bar]( Foo& dest ) { dest = bar; } ); \endcode - You may use \p boost:ref construction to pass functor \p f by reference. - - Requirements The functor \p Func should not throw any exception. */ - template - bool enqueue( const Type& data, Func f ) + template + bool enqueue_with( Func f ) { - scoped_node_ptr p( alloc_node()); - f( p->m_value, data ); + scoped_node_ptr p( alloc_node() ); + f( p->m_value ); if ( base_class::enqueue( *p )) { p.release(); return true; @@ -275,6 +316,19 @@ namespace cds { namespace container { return false; } + /// Synonym for \p enqueue() function + bool push( const value_type& val ) + { + return enqueue( val ); + } + + /// Synonym for \p enqueue_with() function + template + bool push_with( Func f ) + { + return enqueue_with( f ); + } + /// Enqueues data of type \ref value_type constructed with std::forward(args)... template bool emplace( Args&&... args ) @@ -287,35 +341,6 @@ namespace cds { namespace container { return false; } - /// Dequeues a value using copy functor - /** - \p Func is a functor called to copy dequeued value to \p dest of type \p Type - which may be differ from type \p T stored in the queue. - The functor's interface is: - \code - struct myFunctor { - void operator()(Type& dest, T const& data) - { - // Code to copy \p data to \p dest - dest = data; - } - }; - \endcode - You may use \p boost:ref construction to pass functor \p f by reference. - - Requirements The functor \p Func should not throw any exception. - */ - template - bool dequeue( Type& dest, Func f ) - { - typename base_class::dequeue_result res; - if ( base_class::do_dequeue( res, true )) { - f( dest, node_traits::to_value_ptr( *res.pNext )->m_value ); - return true; - } - return false; - } - /// Dequeues a value from the queue /** If queue is not empty, the function returns \p true, \p dest contains copy of @@ -324,40 +349,49 @@ namespace cds { namespace container { */ bool dequeue( value_type& dest ) { - typedef cds::details::trivial_assign functor; - return dequeue( dest, functor() ); + return dequeue_with( [&dest]( value_type& src ) { dest = src; } ); } - /// Synonym for \ref enqueue function - bool push( const value_type& val ) - { - return enqueue( val ); - } - - /// Synonym for template version of \ref enqueue function - template - bool push( const Type& data, Func f ) + /// 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 + cds:container::BasketQueue< cds::gc::HP, Foo > myQueue; + Bar bar; + myQueue.dequeue_with( [&bar]( Foo& src ) { bar = std::move( src );}); + \endcode + The functor is called only if the queue is not empty. + */ + template + bool dequeue_with( Func f ) { - return enqueue( data, f ); + typename base_class::dequeue_result res; + if ( base_class::do_dequeue( res, true )) { + f( node_traits::to_value_ptr( *res.pNext )->m_value ); + base_class::dispose_result( res ); + return true; + } + return false; } - /// Synonym for \ref dequeue function + /// Synonym for \p dequeue() function bool pop( value_type& dest ) { return dequeue( dest ); } - /// Synonym for template version of \ref dequeue function - template - bool pop( Type& dest, Func f ) + /// Synonym for \p dequeue_with() function + template + bool pop_with( Func f ) { - return dequeue( dest, f ); + return dequeue_with( f ); } /// Checks if the queue is empty /** Note that this function is not \p const. - The function is based on \ref dequeue algorithm. + The function is based on \p dequeue() algorithm. */ bool empty() { @@ -372,6 +406,21 @@ namespace cds { namespace container { { base_class::clear(); } + + /// Returns queue's item count + /** \copydetails cds::intrusive::BasketQueue::size() + */ + size_t size() const + { + return base_class::size(); + } + + /// Returns reference to internal statistics + const stat& statistics() const + { + return base_class::statistics(); + } + }; }} // namespace cds::container diff --git a/cds/container/msqueue.h b/cds/container/msqueue.h index 94e589c2..3592fe3c 100644 --- a/cds/container/msqueue.h +++ b/cds/container/msqueue.h @@ -257,7 +257,7 @@ namespace cds { namespace container { \p Func is a functor called to create node. The functor \p f takes one argument - a reference to a new node of type \ref value_type : \code - cds:container::MSQueue< cds::gc::HP, Foo > myQueue; + cds::container::MSQueue< cds::gc::HP, Foo > myQueue; Bar bar; myQueue.enqueue_with( [&bar]( Foo& dest ) { dest = bar; } ); \endcode diff --git a/cds/intrusive/basket_queue.h b/cds/intrusive/basket_queue.h index 46f2ca0a..d825142e 100644 --- a/cds/intrusive/basket_queue.h +++ b/cds/intrusive/basket_queue.h @@ -4,12 +4,8 @@ #define __CDS_INTRUSIVE_BASKET_QUEUE_H #include -#include // ref -#include -#include -#include #include -#include +#include namespace cds { namespace intrusive { @@ -19,18 +15,19 @@ namespace cds { namespace intrusive { namespace basket_queue { /// BasketQueue node /** + Template parameters: Template parameters: - GC - garbage collector used - - Tag - a tag used to distinguish between different implementation - */ + - Tag - a \ref cds_intrusive_hook_tag "tag" + */ template - struct node: public GC::container_node + struct node { typedef GC gc ; ///< Garbage collector typedef Tag tag ; ///< tag - typedef cds::details::marked_ptr marked_ptr ; ///< marked pointer - typedef typename gc::template atomic_marked_ptr< marked_ptr> atomic_marked_ptr ; ///< atomic marked pointer specific for GC + typedef cds::details::marked_ptr marked_ptr; ///< marked pointer + typedef typename gc::template atomic_marked_ptr< marked_ptr> atomic_marked_ptr; ///< atomic marked pointer specific for GC /// Rebind node for other template parameters template @@ -45,56 +42,7 @@ namespace cds { namespace intrusive { {} }; - //@cond - // Specialization for HRC GC - template - struct node< gc::HRC, Tag>: public gc::HRC::container_node - { - typedef gc::HRC gc ; ///< Garbage collector - typedef Tag tag ; ///< tag - - typedef cds::details::marked_ptr marked_ptr ; ///< marked pointer - typedef typename gc::template atomic_marked_ptr< marked_ptr> atomic_marked_ptr ; ///< atomic marked pointer specific for GC - - atomic_marked_ptr m_pNext ; ///< pointer to the next node in the container - - node() - : m_pNext( nullptr ) - {} - - protected: - virtual void cleanUp( cds::gc::hrc::ThreadGC * pGC ) - { - assert( pGC != nullptr ); - typename gc::template GuardArray<2> aGuards( *pGC ); - - while ( true ) { - marked_ptr pNext = aGuards.protect( 0, m_pNext ); - if ( pNext.ptr() && pNext->m_bDeleted.load(atomics::memory_order_acquire) ) { - marked_ptr p = aGuards.protect( 1, pNext->m_pNext ); - m_pNext.compare_exchange_strong( pNext, p, atomics::memory_order_acquire, atomics::memory_order_relaxed ); - continue; - } - else { - break; - } - } - } - - virtual void terminate( cds::gc::hrc::ThreadGC * pGC, bool bConcurrent ) - { - if ( bConcurrent ) { - marked_ptr pNext = m_pNext.load(atomics::memory_order_relaxed); - do {} while ( !m_pNext.compare_exchange_weak( pNext, marked_ptr(), atomics::memory_order_release, atomics::memory_order_relaxed ) ); - } - else { - m_pNext.store( marked_ptr(), atomics::memory_order_relaxed ); - } - } - }; - //@endcond - - using single_link::default_hook; + using cds::intrusive::single_link::default_hook; //@cond template < typename HookType, typename... Options> @@ -113,7 +61,7 @@ namespace cds { namespace intrusive { /** \p Options are: - opt::gc - garbage collector used. - - opt::tag - tag + - opt::tag - a \ref cds_intrusive_hook_tag "tag" */ template < typename... Options > struct base_hook: public hook< opt::base_hook_tag, Options... > @@ -126,7 +74,7 @@ namespace cds { namespace intrusive { \p Options are: - opt::gc - garbage collector used. - - opt::tag - tag + - opt::tag - a \ref cds_intrusive_hook_tag "tag" */ template < size_t MemberOffset, typename... Options > struct member_hook: public hook< opt::member_hook_tag, Options... > @@ -143,7 +91,7 @@ namespace cds { namespace intrusive { \p Options are: - opt::gc - garbage collector used. - - opt::tag - tag + - opt::tag - a \ref cds_intrusive_hook_tag "tag" */ template struct traits_hook: public hook< opt::traits_hook_tag, Options... > @@ -153,25 +101,40 @@ namespace cds { namespace intrusive { //@endcond }; - /// Metafunction for selecting appropriate link checking policy - template < typename Node, opt::link_check_type LinkType > using get_link_checker = single_link::get_link_checker< Node, LinkType >; - - /// Basket queue internal statistics. May be used for debugging or profiling + /// BasketQueue internal statistics. May be used for debugging or profiling /** - Basket queue statistics derives from cds::intrusive::queue_stat - and extends it by two additional fields specific for the algorithm. + Template argument \p Counter defines type of counter. + Default is \p cds::atomicity::event_counter, that is weak, i.e. it is not guaranteed + strict event counting. + You may use stronger type of counter like as \p cds::atomicity::item_counter, + or even integral type, for example, \p int. */ template - struct stat: public cds::intrusive::queue_stat< Counter > + struct stat { - //@cond - typedef cds::intrusive::queue_stat< Counter > base_class; - typedef typename base_class::counter_type counter_type; - //@endcond - - counter_type m_TryAddBasket ; ///< Count of attemps adding new item to a basket (only or BasketQueue, for other queue this metric is not used) - counter_type m_AddBasketCount ; ///< Count of events "Enqueue a new item into basket" (only or BasketQueue, for other queue this metric is not used) - + typedef Counter counter_type; ///< Counter type + + counter_type m_EnqueueCount; ///< Enqueue call count + counter_type m_DequeueCount; ///< Dequeue call count + counter_type m_EnqueueRace; ///< Count of enqueue race conditions encountered + counter_type m_DequeueRace; ///< Count of dequeue race conditions encountered + counter_type m_AdvanceTailError;///< Count of "advance tail failed" events + counter_type m_BadTail; ///< Count of events "Tail is not pointed to the last item in the queue" + counter_type m_TryAddBasket; ///< Count of attemps adding new item to a basket (only or BasketQueue, for other queue this metric is not used) + counter_type m_AddBasketCount; ///< Count of events "Enqueue a new item into basket" (only or BasketQueue, for other queue this metric is not used) + + /// Register enqueue call + void onEnqueue() { ++m_EnqueueCount; } + /// Register dequeue call + void onDequeue() { ++m_DequeueCount; } + /// Register enqueue race event + void onEnqueueRace() { ++m_EnqueueRace; } + /// Register dequeue race event + void onDequeueRace() { ++m_DequeueRace; } + /// Register "advance tail failed" event + void onAdvanceTailFailed() { ++m_AdvanceTailError; } + /// Register event "Tail is not pointed to last item in the queue" + void onBadTail() { ++m_BadTail; } /// Register an attempt t add new item to basket void onTryAddBasket() { ++m_TryAddBasket; } /// Register event "Enqueue a new item into basket" (only or BasketQueue, for other queue this metric is not used) @@ -180,36 +143,130 @@ namespace cds { namespace intrusive { //@cond void reset() { - base_class::reset(); + m_EnqueueCount.reset(); + m_DequeueCount.reset(); + m_EnqueueRace.reset(); + m_DequeueRace.reset(); + m_AdvanceTailError.reset(); + m_BadTail.reset(); m_TryAddBasket.reset(); m_AddBasketCount.reset(); } stat& operator +=( stat const& s ) { - base_class::operator +=( s ); - m_TryAddBasket += s.m_TryAddBasket.get(); + m_EnqueueCount += s.m_EnqueueCount.get(); + m_DequeueCount += s.m_DequeueCount.get(); + m_EnqueueRace += s.m_EnqueueRace.get(); + m_DequeueRace += s.m_DequeueRace.get(); + m_AdvanceTailError += s.m_AdvanceTailError.get(); + m_BadTail += s.m_BadTail.get(); + m_TryAddBasket += s.m_TryAddBasket.get(); m_AddBasketCount += s.m_AddBasketCount.get(); return *this; } //@endcond }; - /// Dummy basket queue statistics - no counting is performed. Support interface like \ref stat - struct dummy_stat: public cds::intrusive::queue_dummy_stat + /// Dummy BasketQueue statistics - no counting is performed, no overhead. Support interface like \p basket_queue::stat + struct empty_stat { //@cond - void onTryAddBasket() {} - void onAddBasket() {} + void onEnqueue() {} + void onDequeue() {} + void onEnqueueRace() {} + void onDequeueRace() {} + void onAdvanceTailFailed() {} + void onBadTail() {} + void onTryAddBasket() {} + void onAddBasket() {} void reset() {} - dummy_stat& operator +=( dummy_stat const& ) + empty_stat& operator +=( empty_stat const& ) { return *this; } //@endcond }; + /// BasketQueue default type traits + struct traits + { + /// Back-off strategy + typedef cds::backoff::empty back_off; + + /// Hook, possible types are \p basket_queue::base_hook, \p basket_queue::member_hook, \p basket_queue::traits_hook + typedef basket_queue::base_hook<> hook; + + /// The functor used for dispose removed items. Default is \p opt::v::empty_disposer. This option is used for dequeuing + typedef opt::v::empty_disposer disposer; + + /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter to enable item counting + typedef atomicity::empty_item_counter item_counter; + + /// Internal statistics (by default, disabled) + /** + Possible option value are: \p basket_queue::stat, \p basket_queue::empty_stat (the default), + user-provided class that supports \p %basket_queue::stat interface. + */ + typedef basket_queue::empty_stat stat; + + /// 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; + + /// Link checking, see \p cds::opt::link_checker + static CDS_CONSTEXPR const opt::link_check_type link_checker = opt::debug_check_link; + + /// Alignment for internal queue data. Default is \p opt::cache_line_alignment + enum { alignment = opt::cache_line_alignment }; + }; + + + /// Metafunction converting option list to \p basket_queue::traits + /** + Supported \p Options are: + + - opt::hook - hook used. Possible hooks are: \p basket_queue::base_hook, \p basket_queue::member_hook, \p basket_queue::traits_hook. + If the option is not specified, \p %basket_queue::base_hook<> is used. + - opt::back_off - back-off strategy used, default is \p cds::backoff::empty. + - opt::disposer - the functor used for dispose removed items. Default is \p opt::v::empty_disposer. This option is used + when dequeuing. + - opt::link_checker - the type of node's link fields checking. Default is \p opt::debug_check_link + - 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 + - opt::stat - the type to gather internal statistics. + Possible statistics types are: \p basket_queue::stat, \p basket_queue::empty_stat, user-provided class that supports \p %basket_queue::stat interface. + Default is \p %basket_queue::empty_stat (internal statistics disabled). + - opt::alignment - the alignment for internal queue data. Default is \p opt::cache_line_alignment + - 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 %BasketQueue with item counting and internal statistics + \code + typedef cds::intrusive::BasketQueue< cds::gc::HP, Foo, + typename cds::intrusive::basket_queue::make_traits< + cds::intrusive::opt:hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc >>, + cds::opt::item_counte< cds::atomicity::item_counter >, + cds::opt::stat< cds::intrusive::basket_queue::stat<> > + >::type + > myQueue; + \endcode + */ + template + 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 basket_queue /// Basket lock-free queue (intrusive variant) @@ -258,38 +315,31 @@ namespace cds { namespace intrusive { oldest basket. It may then dequeue any node in the oldest basket. Template arguments: - - \p GC - garbage collector type: gc::HP, gc::HRC, gc::PTB - - \p T - type to be stored in the queue, should be convertible to \ref single_link::node - - \p Options - options - - Type of node: \ref single_link::node - - \p Options are: - - opt::hook - hook used. Possible values are: basket_queue::base_hook, basket_queue::member_hook, basket_queue::traits_hook. - If the option is not specified, basket_queue::base_hook<> is used. - For Gidenstam's gc::HRC, only basket_queue::base_hook is supported. - - opt::back_off - back-off strategy used. If the option is not specified, the cds::backoff::empty is used. - - opt::disposer - the functor used for dispose removed items. Default is opt::v::empty_disposer. This option is used - in \ref dequeue function. - - opt::link_checker - the type of node's link fields checking. Default is \ref opt::debug_check_link - Note: for gc::HRC garbage collector, link checking policy is always selected as \ref opt::always_check_link. - - opt::item_counter - the type of item counting feature. Default is \ref atomicity::empty_item_counter (no item counting feature) - - opt::stat - the type to gather internal statistics. - Possible option value are: \ref basket_queue::stat, \ref basket_queue::dummy_stat, - user-provided class that supports basket_queue::stat interface. - Default is \ref basket_queue::dummy_stat. - Generic option intrusive::queue_stat and intrusive::queue_dummy_stat are acceptable too, however, - they will be automatically converted to basket_queue::stat and basket_queue::dummy_stat - respectively. - - 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). - - Garbage collecting schema \p GC must be consistent with the basket_queue::node GC. + - \p GC - garbage collector type: \p gc::HP, \p gc::DHP + - \p T - type of value to be stored in the queue + - \p Traits - queue traits, default is \p basket_queue::traits. You can use \p basket_queue::make_traits + metafunction to make your traits or just derive your traits from \p %basket_queue::traits: + \code + struct myTraits: public cds::intrusive::basket_queue::traits { + typedef cds::intrusive::basket_queue::stat<> stat; + typedef cds::atomicity::item_counter item_counter; + }; + typedef cds::intrusive::BasketQueue< cds::gc::HP, Foo, myTraits > myQueue; + + // Equivalent make_traits example: + typedef cds::intrusive::BasketQueue< cds::gc::HP, Foo, + typename cds::intrusive::basket_queue::make_traits< + cds::opt::stat< cds::intrusive::basket_queue::stat<> >, + cds::opt::item_counter< cds::atomicity::item_counter > + >::type + > myQueue; + \endcode + + Garbage collecting schema \p GC must be consistent with the \p basket_queue::node GC. \par About item disposing - Like MSQueue, the Baskets queue algo has a key feature: even if the queue is empty it contains one item that is "dummy" one from - the standpoint of the algo. See \ref dequeue function doc for explanation. + Like \p MSQueue, the Baskets queue algo has a key feature: even if the queue is empty it contains one item that is "dummy" one from + the standpoint of the algo. See \p dequeue() function doc for explanation. \par Examples \code @@ -314,13 +364,11 @@ namespace cds { namespace intrusive { } }; - typedef ci::BasketQueue< hp_gc, - Foo - ,ci::opt::hook< - ci::basket_queue::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< fooDisposer > - > fooQueue; + struct fooTraits: public ci::basket_queue::traits { + typedef ci::basket_queue::base_hook< ci::opt::gc > hook; + typedef fooDisposer disposer; + }; + typedef ci::BasketQueue< hp_gc, Foo, fooTraits > fooQueue; // BasketQueue with Hazard Pointer garbage collector, // member hook + item disposer + item counter, @@ -332,111 +380,63 @@ namespace cds { namespace intrusive { ci::basket_queue::node< hp_gc > hMember; }; - typedef ci::BasketQueue< hp_gc, - Foo - ,ci::opt::hook< - ci::basket_queue::member_hook< - offsetof(Bar, hMember) - ,ci::opt::gc + struct barTraits: public + ci::basket_queue::make_traits< + ci::opt::hook< + ci::basket_queue::member_hook< + offsetof(Bar, hMember) + ,ci::opt::gc + > > - > - ,ci::opt::disposer< fooDisposer > - ,cds::opt::item_counter< cds::atomicity::item_counter > - ,cds::opt::alignment< cds::opt::no_special_alignment > - > barQueue; + ,ci::opt::disposer< fooDisposer > + ,cds::opt::item_counter< cds::atomicity::item_counter > + ,cds::opt::alignment< cds::opt::no_special_alignment > + >::type + {}; + typedef ci::BasketQueue< hp_gc, Bar, barTraits > barQueue; \endcode */ - template + template class BasketQueue { - //@cond - struct default_options - { - typedef cds::backoff::empty back_off; - typedef basket_queue::base_hook<> hook; - typedef opt::v::empty_disposer disposer; - typedef atomicity::empty_item_counter item_counter; - typedef basket_queue::dummy_stat stat; - typedef opt::v::relaxed_ordering memory_model; - static const opt::link_check_type link_checker = opt::debug_check_link; - 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; - - typedef typename std::conditional< - std::is_same >::value - ,basket_queue::stat<> - ,typename std::conditional< - std::is_same::value - ,basket_queue::dummy_stat - ,typename options::stat - >::type - >::type stat_type_; - - //@endcond - - public: - typedef T value_type ; ///< type of value stored in the queue - typedef typename options::hook hook ; ///< hook type - typedef typename hook::node_type node_type ; ///< node type - typedef typename options::disposer disposer ; ///< disposer used - typedef typename get_node_traits< value_type, node_type, hook>::type node_traits ; ///< node traits - typedef typename basket_queue::get_link_checker< node_type, options::link_checker >::type link_checker ; ///< link checker - - typedef GC gc ; ///< Garbage collector - typedef typename options::back_off back_off ; ///< back-off strategy - typedef typename options::item_counter item_counter ; ///< Item counting policy used -#ifdef CDS_DOXYGEN_INVOKED - typedef typename options::stat stat ; ///< Internal statistics policy used -#else - typedef stat_type_ stat; -#endif - typedef typename options::memory_model memory_model ; ///< Memory ordering. See cds::opt::memory_model option + typedef GC gc; ///< Garbage collector + typedef T value_type; ///< type of value stored in the queue + typedef Traits traits; ///< Queue traits + typedef typename traits::hook hook; ///< hook type + typedef typename hook::node_type node_type; ///< node type + typedef typename traits::disposer disposer; ///< disposer used + typedef typename get_node_traits< value_type, node_type, hook>::type node_traits; ///< node traits + typedef typename single_link::get_link_checker< node_type, traits::link_checker >::type link_checker; ///< link checker + + typedef typename traits::back_off back_off; ///< back-off strategy + typedef typename traits::item_counter item_counter; ///< Item counting policy used + typedef typename traits::stat stat; ///< Internal statistics policy used + typedef typename traits::memory_model memory_model; ///< Memory ordering. See cds::opt::memory_model option /// Rebind template arguments - template + template struct rebind { - typedef BasketQueue< GC2, T2, Options2...> other ; ///< Rebinding result + typedef BasketQueue< GC2, T2, Traits2> other ; ///< Rebinding result }; - static const size_t m_nHazardPtrCount = 6 ; ///< Count of hazard pointer required for the algorithm + static CDS_CONSTEXPR const size_t m_nHazardPtrCount = 6 ; ///< Count of hazard pointer required for the algorithm protected: //@cond - - struct internal_disposer - { - void operator()( value_type * p ) - { - assert( p != nullptr ); - - BasketQueue::clear_links( node_traits::to_node_ptr(p) ); - disposer()( p ); - } - }; - typedef typename node_type::marked_ptr marked_ptr; typedef typename node_type::atomic_marked_ptr atomic_marked_ptr; typedef intrusive::node_to_value node_to_value; - typedef typename opt::details::alignment_setter< atomic_marked_ptr, options::alignment >::type aligned_node_ptr; - typedef typename opt::details::alignment_setter< - cds::intrusive::details::dummy_node< gc, node_type>, - options::alignment - >::type dummy_node_type; + typedef typename opt::details::alignment_setter< atomic_marked_ptr, traits::alignment >::type aligned_node_ptr; + typedef typename opt::details::alignment_setter< node_type, options::alignment >::type dummy_node_type; + // GC and node_type::gc must be the same + static_assert( std::is_same::value, "GC and node_type::gc must be the same"); //@endcond aligned_node_ptr m_pHead ; ///< Queue's head pointer (aligned) aligned_node_ptr m_pTail ; ///< Queue's tail pointer (aligned) - dummy_node_type m_Dummy ; ///< dummy node item_counter m_ItemCounter ; ///< Item counter stat m_Stat ; ///< Internal statistics @@ -578,6 +578,15 @@ namespace cds { namespace intrusive { void dispose_node( node_type * p ) { if ( p != m_Dummy.get() ) { + struct internal_disposer + { + void operator()( value_type * p ) + { + assert( p != nullptr ); + BasketQueue::clear_links( node_traits::to_node_ptr( p ) ); + disposer()(p); + } + }; gc::template retire( node_traits::to_value_ptr(p) ); } else @@ -588,27 +597,10 @@ namespace cds { namespace intrusive { public: /// Initializes empty queue BasketQueue() - : m_pHead( nullptr ) - , m_pTail( nullptr ) + : m_pHead( &m_Dummy ) + , m_pTail( &m_Dummy ) , m_nMaxHops( 3 ) - { - // GC and node_type::gc must be the same - static_assert(( std::is_same::value ), "GC and node_type::gc must be the same"); - - // For cds::gc::HRC, only one base_hook is allowed - static_assert(( - std::conditional< - std::is_same::value, - std::is_same< typename hook::hook_type, opt::base_hook_tag >, - boost::true_type - >::type::value - ), "For cds::gc::HRC, only base_hook is allowed"); - - // Head/tail initialization should be made via store call - // because of gc::HRC manages reference counting - m_pHead.store( marked_ptr(m_Dummy.get()), memory_model::memory_order_relaxed ); - m_pTail.store( marked_ptr(m_Dummy.get()), memory_model::memory_order_relaxed ); - } + {} /// Destructor clears the queue /** @@ -640,25 +632,6 @@ namespace cds { namespace intrusive { dispose_node( pHead ); } - /// Returns queue's item count - /** - The value returned depends on opt::item_counter option. For atomicity::empty_item_counter, - this function always returns 0. - - Warning: even if you use real item counter and it returns 0, this fact is not mean that the queue - is empty. To check queue emptyness use \ref empty() method. - */ - size_t size() const - { - return m_ItemCounter.value(); - } - - /// Returns reference to internal statistics - const stat& statistics() const - { - return m_Stat; - } - /// Enqueues \p val value into the queue. /** @anchor cds_intrusive_BasketQueue_enqueue The function always returns \p true. @@ -748,11 +721,17 @@ namespace cds { namespace intrusive { return true; } + /// Synonym for \p enqueue() function + bool push( value_type& val ) + { + return enqueue( val ); + } + /// Dequeues a value from the queue /** @anchor cds_intrusive_BasketQueue_dequeue If the queue is empty the function returns \p nullptr. - Warning: see MSQueue::deque note about item disposing + @note See \p MSQueue::dequeue() note about item disposing */ value_type * dequeue() { @@ -763,13 +742,7 @@ namespace cds { namespace intrusive { return nullptr; } - /// Synonym for \ref cds_intrusive_BasketQueue_enqueue "enqueue" function - bool push( value_type& val ) - { - return enqueue( val ); - } - - /// Synonym for \ref cds_intrusive_BasketQueue_dequeue "dequeue" function + /// Synonym for \p dequeue() function value_type * pop() { return dequeue(); @@ -778,8 +751,8 @@ namespace cds { namespace intrusive { /// Checks if the queue is empty /** Note that this function is not \p const. - The function is based on \ref dequeue algorithm - but really does not dequeued any item. + The function is based on \p dequeue() algorithm + but really it does not dequeue any item. */ bool empty() { @@ -789,14 +762,33 @@ namespace cds { namespace intrusive { /// Clear the queue /** - The function repeatedly calls \ref dequeue until it returns \p nullptr. - The disposer defined in template \p Options is called for each item + The function repeatedly calls \p dequeue() until it returns \p nullptr. + The disposer defined in template \p Traits is called for each item that can be safely disposed. */ void clear() { while ( dequeue() ); } + + /// Returns queue's item count + /** + The value returned depends on \p Traits (see basket_queue::traits::item_counter). For \p atomicity::empty_item_counter, + this function always returns 0. + + @note Even if you use real item counter and it returns 0, this fact is not mean that the queue + is empty. To check queue emptyness use \p empty() method. + */ + size_t size() const + { + return m_ItemCounter.value(); + } + + /// Returns reference to internal statistics + const stat& statistics() const + { + return m_Stat; + } }; }} // namespace cds::intrusive diff --git a/cds/intrusive/msqueue.h b/cds/intrusive/msqueue.h index 972ff808..164ef2ca 100644 --- a/cds/intrusive/msqueue.h +++ b/cds/intrusive/msqueue.h @@ -67,7 +67,7 @@ namespace cds { namespace intrusive { template struct stat { - typedef Counter counter_type ; ///< Counter type + typedef Counter counter_type; ///< Counter type counter_type m_EnqueueCount ; ///< Enqueue call count counter_type m_DequeueCount ; ///< Dequeue call count @@ -115,8 +115,6 @@ namespace cds { namespace intrusive { }; /// Dummy queue statistics - no counting is performed, no overhead. Support interface like \p msqueue::stat - /** @ingroup cds_intrusive_helper - */ struct empty_stat { //@cond @@ -167,7 +165,7 @@ namespace cds { namespace intrusive { /// Link checking, see \p cds::opt::link_checker static CDS_CONSTEXPR const opt::link_check_type link_checker = opt::debug_check_link; - /// Alignment of internal queue data. Default is \p opt::cache_line_alignment + /// Alignment for internal queue data. Default is \p opt::cache_line_alignment enum { alignment = opt::cache_line_alignment }; }; @@ -186,7 +184,7 @@ namespace cds { namespace intrusive { To enable item counting use \p cds::atomicity::item_counter - opt::stat - the type to gather internal statistics. Possible statistics types are: \p msqueue::stat, \p msqueue::empty_stat, user-provided class that supports \p %msqueue::stat interface. - Default is \p %msqueue::empty_stat. + Default is \p %msqueue::empty_stat (internal statistics disabled). - opt::alignment - the alignment for internal queue data. Default is \p opt::cache_line_alignment - 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). @@ -224,7 +222,7 @@ namespace cds { namespace intrusive { Template arguments: - \p GC - garbage collector type: \p gc::HP, \p gc::DHP - - \p T - type to be stored in the queue. A value of type \p T must be derived from \p msqueue::node for \p msqueue::base_hook, + - \p T - type of value to be stored in the queue. A value of type \p T must be derived from \p msqueue::node for \p msqueue::base_hook, or it should have a member of type \p %msqueue::node for \p msqueue::member_hook, or it should be convertible to \p %msqueue::node for \p msqueue::traits_hook. - \p Traits - queue traits, default is \p msqueue::traits. You can use \p msqueue::make_traits @@ -336,6 +334,8 @@ namespace cds { namespace intrusive { typedef MSQueue< GC2, T2, Traits2 > other; ///< Rebinding result }; + static CDS_CONSTEXPR const size_t m_nHazardPtrCount = 2; ///< Count of hazard pointer required for the algorithm + protected: //@cond diff --git a/projects/Win/vc12/hdr-test-queue.vcxproj b/projects/Win/vc12/hdr-test-queue.vcxproj index 72ea162d..2eeb7ee8 100644 --- a/projects/Win/vc12/hdr-test-queue.vcxproj +++ b/projects/Win/vc12/hdr-test-queue.vcxproj @@ -535,14 +535,12 @@ - - - + + + - - @@ -566,7 +564,6 @@ - diff --git a/projects/Win/vc12/hdr-test-queue.vcxproj.filters b/projects/Win/vc12/hdr-test-queue.vcxproj.filters index 67800298..eb90ff49 100644 --- a/projects/Win/vc12/hdr-test-queue.vcxproj.filters +++ b/projects/Win/vc12/hdr-test-queue.vcxproj.filters @@ -1,27 +1,12 @@  - - container - - - container - - - container - container intrusive - - intrusive - - - intrusive - intrusive @@ -86,11 +71,17 @@ container + + intrusive + + + container + + + container + - - intrusive - intrusive diff --git a/projects/source.test-hdr.mk b/projects/source.test-hdr.mk index a542c5bb..b0f18002 100644 --- a/projects/source.test-hdr.mk +++ b/projects/source.test-hdr.mk @@ -117,15 +117,13 @@ CDS_TESTHDR_PQUEUE := \ CDS_TESTHDR_QUEUE := \ tests/test-hdr/queue/hdr_queue_register.cpp \ - tests/test-hdr/queue/hdr_intrusive_basketqueue_hrc.cpp \ tests/test-hdr/queue/hdr_intrusive_fcqueue.cpp \ tests/test-hdr/queue/hdr_intrusive_segmented_queue_hp.cpp \ tests/test-hdr/queue/hdr_intrusive_segmented_queue_ptb.cpp \ tests/test-hdr/queue/hdr_intrusive_tsigas_cycle_queue.cpp \ tests/test-hdr/queue/hdr_intrusive_vyukovmpmc_cycle_queue.cpp \ - tests/test-hdr/queue/hdr_basketqueue_hrc.cpp \ - tests/test-hdr/queue/hdr_basketqueue_hzp.cpp \ - tests/test-hdr/queue/hdr_basketqueue_ptb.cpp \ + tests/test-hdr/queue/hdr_basketqueue_hp.cpp \ + tests/test-hdr/queue/hdr_basketqueue_dhp.cpp \ tests/test-hdr/queue/hdr_fcqueue.cpp \ tests/test-hdr/queue/hdr_moirqueue_hp.cpp \ tests/test-hdr/queue/hdr_moirqueue_dhp.cpp \ diff --git a/projects/source.test-hdr.offsetof.mk b/projects/source.test-hdr.offsetof.mk index 12eebea5..60985c89 100644 --- a/projects/source.test-hdr.offsetof.mk +++ b/projects/source.test-hdr.offsetof.mk @@ -68,7 +68,7 @@ CDS_TESTHDR_OFFSETOF_ORDLIST := \ CDS_TESTHDR_OFFSETOF_QUEUE := \ tests/test-hdr/queue/hdr_intrusive_basketqueue_hp.cpp \ - tests/test-hdr/queue/hdr_intrusive_basketqueue_ptb.cpp \ + tests/test-hdr/queue/hdr_intrusive_basketqueue_dhp.cpp \ tests/test-hdr/queue/hdr_intrusive_moirqueue_hp.cpp \ tests/test-hdr/queue/hdr_intrusive_moirqueue_dhp.cpp \ tests/test-hdr/queue/hdr_intrusive_msqueue_hp.cpp \ diff --git a/tests/test-hdr/queue/hdr_basketqueue_dhp.cpp b/tests/test-hdr/queue/hdr_basketqueue_dhp.cpp new file mode 100644 index 00000000..66034cd6 --- /dev/null +++ b/tests/test-hdr/queue/hdr_basketqueue_dhp.cpp @@ -0,0 +1,115 @@ +//$$CDS-header$$ + +#include +#include + +#include "queue/hdr_queue_new.h" + +namespace queue { + + void HdrTestQueue::BasketQueue_DHP() + { + typedef cds::container::BasketQueue< cds::gc::DHP, int > queue_type; + test_no_ic< queue_type >(); + } + + void HdrTestQueue::BasketQueue_DHP_Counted() + { + struct traits : public cds::container::basket_queue::traits + { + typedef cds::atomicity::item_counter item_counter; + }; + typedef cds::container::BasketQueue< cds::gc::DHP, int, traits > queue_type; + test_ic< queue_type >(); + } + + void HdrTestQueue::BasketQueue_DHP_relax() + { + struct traits : public + cds::container::basket_queue::make_traits < + cds::opt::memory_model< cds::opt::v::relaxed_ordering> + > ::type + {}; + typedef cds::container::BasketQueue< cds::gc::DHP, int, traits > queue_type; + test_no_ic< queue_type >(); + } + + void HdrTestQueue::BasketQueue_DHP_Counted_relax() + { + typedef cds::container::BasketQueue< cds::gc::DHP, int, + typename cds::container::basket_queue::make_traits < + cds::opt::item_counter< cds::atomicity::item_counter > + ,cds::opt::memory_model< cds::opt::v::relaxed_ordering> + >::type + > queue_type; + test_ic< queue_type >(); + } + + void HdrTestQueue::BasketQueue_DHP_seqcst() + { + struct traits : public cds::container::basket_queue::traits + { + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef cds::container::BasketQueue< cds::gc::DHP, int, traits > queue_type; + test_no_ic< queue_type >(); + } + + void HdrTestQueue::BasketQueue_DHP_Counted_seqcst() + { + typedef cds::container::BasketQueue < cds::gc::DHP, int, + typename cds::container::basket_queue::make_traits < + cds::opt::item_counter< cds::atomicity::item_counter > + ,cds::opt::memory_model< cds::opt::v::sequential_consistent> + >::type + > queue_type; + test_ic< queue_type >(); + } + + void HdrTestQueue::BasketQueue_DHP_relax_align() + { + typedef cds::container::BasketQueue < cds::gc::DHP, int, + typename cds::container::basket_queue::make_traits < + cds::opt::memory_model< cds::opt::v::relaxed_ordering> + ,cds::opt::alignment< 16 > + >::type + > queue_type; + test_ic< queue_type >(); + } + + void HdrTestQueue::BasketQueue_DHP_Counted_relax_align() + { + struct traits : public cds::container::basket_queue::traits + { + typedef cds::atomicity::item_counter item_counter; + typedef cds::opt::v::relaxed_ordering memory_model; + enum { alignment = 32 }; + }; + typedef cds::container::BasketQueue < cds::gc::DHP, int, traits > queue_type; + test_ic< queue_type >( 0 ); + } + + void HdrTestQueue::BasketQueue_DHP_seqcst_align() + { + typedef cds::container::BasketQueue < cds::gc::DHP, int, + typename cds::container::basket_queue::make_traits < + cds::opt::memory_model< cds::opt::v::sequential_consistent> + , cds::opt::alignment< cds::opt::no_special_alignment > + > ::type + > queue_type; + test_no_ic< queue_type >(); + } + + void HdrTestQueue::BasketQueue_DHP_Counted_seqcst_align() + { + typedef cds::container::BasketQueue < cds::gc::DHP, int, + typename cds::container::basket_queue::make_traits < + cds::opt::item_counter< cds::atomicity::item_counter > + ,cds::opt::memory_model< cds::opt::v::sequential_consistent> + ,cds::opt::alignment< cds::opt::cache_line_alignment > + > ::type + > queue_type; + test_no_ic< queue_type >(); + } + +} // namespace queue diff --git a/tests/test-hdr/queue/hdr_basketqueue_hp.cpp b/tests/test-hdr/queue/hdr_basketqueue_hp.cpp new file mode 100644 index 00000000..80b2a5b4 --- /dev/null +++ b/tests/test-hdr/queue/hdr_basketqueue_hp.cpp @@ -0,0 +1,115 @@ +//$$CDS-header$$ + +#include +#include + +#include "queue/hdr_queue_new.h" + +namespace queue { + + void HdrTestQueue::BasketQueue_HP() + { + typedef cds::container::BasketQueue< cds::gc::HP, int > queue_type; + test_no_ic< queue_type >(); + } + + void HdrTestQueue::BasketQueue_HP_Counted() + { + struct traits : public cds::container::basket_queue::traits + { + typedef cds::atomicity::item_counter item_counter; + }; + typedef cds::container::BasketQueue< cds::gc::HP, int, traits > queue_type; + test_ic< queue_type >(); + } + + void HdrTestQueue::BasketQueue_HP_relax() + { + struct traits : public + cds::container::basket_queue::make_traits < + cds::opt::memory_model< cds::opt::v::relaxed_ordering> + > ::type + {}; + typedef cds::container::BasketQueue< cds::gc::HP, int, traits > queue_type; + test_no_ic< queue_type >(); + } + + void HdrTestQueue::BasketQueue_HP_Counted_relax() + { + typedef cds::container::BasketQueue< cds::gc::HP, int, + typename cds::container::basket_queue::make_traits < + cds::opt::item_counter< cds::atomicity::item_counter > + ,cds::opt::memory_model< cds::opt::v::relaxed_ordering> + >::type + > queue_type; + test_ic< queue_type >(); + } + + void HdrTestQueue::BasketQueue_HP_seqcst() + { + struct traits : public cds::container::basket_queue::traits + { + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef cds::container::BasketQueue< cds::gc::HP, int, traits > queue_type; + test_no_ic< queue_type >(); + } + + void HdrTestQueue::BasketQueue_HP_Counted_seqcst() + { + typedef cds::container::BasketQueue < cds::gc::HP, int, + typename cds::container::basket_queue::make_traits < + cds::opt::item_counter< cds::atomicity::item_counter > + ,cds::opt::memory_model< cds::opt::v::sequential_consistent> + >::type + > queue_type; + test_ic< queue_type >(); + } + + void HdrTestQueue::BasketQueue_HP_relax_align() + { + typedef cds::container::BasketQueue < cds::gc::HP, int, + typename cds::container::basket_queue::make_traits < + cds::opt::memory_model< cds::opt::v::relaxed_ordering> + ,cds::opt::alignment< 16 > + >::type + > queue_type; + test_ic< queue_type >(); + } + + void HdrTestQueue::BasketQueue_HP_Counted_relax_align() + { + struct traits : public cds::container::basket_queue::traits + { + typedef cds::atomicity::item_counter item_counter; + typedef cds::opt::v::relaxed_ordering memory_model; + enum { alignment = 32 }; + }; + typedef cds::container::BasketQueue < cds::gc::HP, int, traits > queue_type; + test_ic< queue_type >( 0 ); + } + + void HdrTestQueue::BasketQueue_HP_seqcst_align() + { + typedef cds::container::BasketQueue < cds::gc::HP, int, + typename cds::container::basket_queue::make_traits < + cds::opt::memory_model< cds::opt::v::sequential_consistent> + , cds::opt::alignment< cds::opt::no_special_alignment > + > ::type + > queue_type; + test_no_ic< queue_type >(); + } + + void HdrTestQueue::BasketQueue_HP_Counted_seqcst_align() + { + typedef cds::container::BasketQueue < cds::gc::HP, int, + typename cds::container::basket_queue::make_traits < + cds::opt::item_counter< cds::atomicity::item_counter > + ,cds::opt::memory_model< cds::opt::v::sequential_consistent> + ,cds::opt::alignment< cds::opt::cache_line_alignment > + > ::type + > queue_type; + test_no_ic< queue_type >(); + } + +} // namespace queue diff --git a/tests/test-hdr/queue/hdr_basketqueue_hrc.cpp b/tests/test-hdr/queue/hdr_basketqueue_hrc.cpp deleted file mode 100644 index bf5f8835..00000000 --- a/tests/test-hdr/queue/hdr_basketqueue_hrc.cpp +++ /dev/null @@ -1,107 +0,0 @@ -//$$CDS-header$$ - -#include -#include - -#include "queue/hdr_queue.h" - -namespace queue { - - void Queue_TestHeader::BasketQueue_HRC() - { - testNoItemCounter< - cds::container::BasketQueue< cds::gc::HRC, int - > - >(); - } - - void Queue_TestHeader::BasketQueue_HRC_Counted() - { - testWithItemCounter< - cds::container::BasketQueue< cds::gc::HRC, int - ,cds::opt::item_counter< cds::atomicity::item_counter > - > - >(); - } - - void Queue_TestHeader::BasketQueue_HRC_relax() - { - testNoItemCounter< - cds::container::BasketQueue< cds::gc::HRC, int - ,cds::opt::memory_model< cds::opt::v::relaxed_ordering> - > - >(); - } - - void Queue_TestHeader::BasketQueue_HRC_Counted_relax() - { - testWithItemCounter< - cds::container::BasketQueue< cds::gc::HRC, int - ,cds::opt::item_counter< cds::atomicity::item_counter > - ,cds::opt::memory_model< cds::opt::v::relaxed_ordering> - > - >(); - } - - void Queue_TestHeader::BasketQueue_HRC_seqcst() - { - testNoItemCounter< - cds::container::BasketQueue< cds::gc::HRC, int - ,cds::opt::memory_model< cds::opt::v::sequential_consistent> - > - >(); - } - - void Queue_TestHeader::BasketQueue_HRC_Counted_seqcst() - { - testWithItemCounter< - cds::container::BasketQueue< cds::gc::HRC, int - ,cds::opt::item_counter< cds::atomicity::item_counter > - ,cds::opt::memory_model< cds::opt::v::sequential_consistent> - > - >(); - } - - void Queue_TestHeader::BasketQueue_HRC_relax_align() - { - testNoItemCounter< - cds::container::BasketQueue< cds::gc::HRC, int - ,cds::opt::memory_model< cds::opt::v::relaxed_ordering> - ,cds::opt::alignment< 16 > - > - >(); - } - - void Queue_TestHeader::BasketQueue_HRC_Counted_relax_align() - { - testWithItemCounter< - cds::container::BasketQueue< cds::gc::HRC, int - ,cds::opt::item_counter< cds::atomicity::item_counter > - ,cds::opt::memory_model< cds::opt::v::relaxed_ordering> - ,cds::opt::alignment< 32 > - > - >(); - } - - void Queue_TestHeader::BasketQueue_HRC_seqcst_align() - { - testNoItemCounter< - cds::container::BasketQueue< cds::gc::HRC, int - ,cds::opt::memory_model< cds::opt::v::sequential_consistent> - ,cds::opt::alignment< cds::opt::no_special_alignment > - > - >(); - } - - void Queue_TestHeader::BasketQueue_HRC_Counted_seqcst_align() - { - testWithItemCounter< - cds::container::BasketQueue< cds::gc::HRC, int - ,cds::opt::item_counter< cds::atomicity::item_counter > - ,cds::opt::memory_model< cds::opt::v::sequential_consistent> - ,cds::opt::alignment< cds::opt::cache_line_alignment > - > - >(); - } - -} // namespace queue diff --git a/tests/test-hdr/queue/hdr_basketqueue_hzp.cpp b/tests/test-hdr/queue/hdr_basketqueue_hzp.cpp deleted file mode 100644 index d9a9955f..00000000 --- a/tests/test-hdr/queue/hdr_basketqueue_hzp.cpp +++ /dev/null @@ -1,107 +0,0 @@ -//$$CDS-header$$ - -#include -#include - -#include "queue/hdr_queue.h" - -namespace queue { - - void Queue_TestHeader::BasketQueue_HP() - { - testNoItemCounter< - cds::container::BasketQueue< cds::gc::HP, int - > - >(); - } - - void Queue_TestHeader::BasketQueue_HP_Counted() - { - testWithItemCounter< - cds::container::BasketQueue< cds::gc::HP, int - ,cds::opt::item_counter< cds::atomicity::item_counter > - > - >(); - } - - void Queue_TestHeader::BasketQueue_HP_relax() - { - testNoItemCounter< - cds::container::BasketQueue< cds::gc::HP, int - ,cds::opt::memory_model< cds::opt::v::relaxed_ordering> - > - >(); - } - - void Queue_TestHeader::BasketQueue_HP_Counted_relax() - { - testWithItemCounter< - cds::container::BasketQueue< cds::gc::HP, int - ,cds::opt::item_counter< cds::atomicity::item_counter > - ,cds::opt::memory_model< cds::opt::v::relaxed_ordering> - > - >(); - } - - void Queue_TestHeader::BasketQueue_HP_seqcst() - { - testNoItemCounter< - cds::container::BasketQueue< cds::gc::HP, int - ,cds::opt::memory_model< cds::opt::v::sequential_consistent> - > - >(); - } - - void Queue_TestHeader::BasketQueue_HP_Counted_seqcst() - { - testWithItemCounter< - cds::container::BasketQueue< cds::gc::HP, int - ,cds::opt::item_counter< cds::atomicity::item_counter > - ,cds::opt::memory_model< cds::opt::v::sequential_consistent> - > - >(); - } - - void Queue_TestHeader::BasketQueue_HP_relax_align() - { - testNoItemCounter< - cds::container::BasketQueue< cds::gc::HP, int - ,cds::opt::memory_model< cds::opt::v::relaxed_ordering> - ,cds::opt::alignment< 16 > - > - >(); - } - - void Queue_TestHeader::BasketQueue_HP_Counted_relax_align() - { - testWithItemCounter< - cds::container::BasketQueue< cds::gc::HP, int - ,cds::opt::item_counter< cds::atomicity::item_counter > - ,cds::opt::memory_model< cds::opt::v::relaxed_ordering> - ,cds::opt::alignment< 32 > - > - >(); - } - - void Queue_TestHeader::BasketQueue_HP_seqcst_align() - { - testNoItemCounter< - cds::container::BasketQueue< cds::gc::HP, int - ,cds::opt::memory_model< cds::opt::v::sequential_consistent> - ,cds::opt::alignment< cds::opt::no_special_alignment > - > - >(); - } - - void Queue_TestHeader::BasketQueue_HP_Counted_seqcst_align() - { - testWithItemCounter< - cds::container::BasketQueue< cds::gc::HP, int - ,cds::opt::item_counter< cds::atomicity::item_counter > - ,cds::opt::memory_model< cds::opt::v::sequential_consistent> - ,cds::opt::alignment< cds::opt::cache_line_alignment > - > - >(); - } - -} // namespace queue diff --git a/tests/test-hdr/queue/hdr_basketqueue_ptb.cpp b/tests/test-hdr/queue/hdr_basketqueue_ptb.cpp deleted file mode 100644 index 4fd1296f..00000000 --- a/tests/test-hdr/queue/hdr_basketqueue_ptb.cpp +++ /dev/null @@ -1,107 +0,0 @@ -//$$CDS-header$$ - -#include -#include - -#include "queue/hdr_queue.h" - -namespace queue { - - void Queue_TestHeader::BasketQueue_PTB() - { - testNoItemCounter< - cds::container::BasketQueue< cds::gc::PTB, int - > - >(); - } - - void Queue_TestHeader::BasketQueue_PTB_Counted() - { - testWithItemCounter< - cds::container::BasketQueue< cds::gc::PTB, int - ,cds::opt::item_counter< cds::atomicity::item_counter > - > - >(); - } - - void Queue_TestHeader::BasketQueue_PTB_relax() - { - testNoItemCounter< - cds::container::BasketQueue< cds::gc::PTB, int - ,cds::opt::memory_model< cds::opt::v::relaxed_ordering> - > - >(); - } - - void Queue_TestHeader::BasketQueue_PTB_Counted_relax() - { - testWithItemCounter< - cds::container::BasketQueue< cds::gc::PTB, int - ,cds::opt::item_counter< cds::atomicity::item_counter > - ,cds::opt::memory_model< cds::opt::v::relaxed_ordering> - > - >(); - } - - void Queue_TestHeader::BasketQueue_PTB_seqcst() - { - testNoItemCounter< - cds::container::BasketQueue< cds::gc::PTB, int - ,cds::opt::memory_model< cds::opt::v::sequential_consistent> - > - >(); - } - - void Queue_TestHeader::BasketQueue_PTB_Counted_seqcst() - { - testWithItemCounter< - cds::container::BasketQueue< cds::gc::PTB, int - ,cds::opt::item_counter< cds::atomicity::item_counter > - ,cds::opt::memory_model< cds::opt::v::sequential_consistent> - > - >(); - } - - void Queue_TestHeader::BasketQueue_PTB_relax_align() - { - testNoItemCounter< - cds::container::BasketQueue< cds::gc::PTB, int - ,cds::opt::memory_model< cds::opt::v::relaxed_ordering> - ,cds::opt::alignment< 16 > - > - >(); - } - - void Queue_TestHeader::BasketQueue_PTB_Counted_relax_align() - { - testWithItemCounter< - cds::container::BasketQueue< cds::gc::PTB, int - ,cds::opt::item_counter< cds::atomicity::item_counter > - ,cds::opt::memory_model< cds::opt::v::relaxed_ordering> - ,cds::opt::alignment< 32 > - > - >(); - } - - void Queue_TestHeader::BasketQueue_PTB_seqcst_align() - { - testNoItemCounter< - cds::container::BasketQueue< cds::gc::PTB, int - ,cds::opt::memory_model< cds::opt::v::sequential_consistent> - ,cds::opt::alignment< cds::opt::no_special_alignment > - > - >(); - } - - void Queue_TestHeader::BasketQueue_PTB_Counted_seqcst_align() - { - testWithItemCounter< - cds::container::BasketQueue< cds::gc::PTB, int - ,cds::opt::item_counter< cds::atomicity::item_counter > - ,cds::opt::memory_model< cds::opt::v::sequential_consistent> - ,cds::opt::alignment< cds::opt::cache_line_alignment > - > - >(); - } - -} // namespace queue diff --git a/tests/test-hdr/queue/hdr_intrusive_basketqueue_dhp.cpp b/tests/test-hdr/queue/hdr_intrusive_basketqueue_dhp.cpp new file mode 100644 index 00000000..04546188 --- /dev/null +++ b/tests/test-hdr/queue/hdr_intrusive_basketqueue_dhp.cpp @@ -0,0 +1,170 @@ +//$$CDS-header$$ + +#include "hdr_intrusive_msqueue.h" +#include +#include + +namespace queue { + +#define TEST(X) void IntrusiveQueueHeaderTest::test_##X() { test_basket(); } + + namespace { + typedef IntrusiveQueueHeaderTest::base_hook_item < ci::basket_queue::node > base_hook_item; + typedef IntrusiveQueueHeaderTest::member_hook_item < ci::basket_queue::node > member_hook_item; + + // DHP base hook + struct traits_BasketQueue_disposer : public + ci::basket_queue::make_traits < ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > >::type + { + typedef ci::basket_queue::base_hook< ci::opt::gc < cds::gc::DHP > > hook; + }; + typedef ci::BasketQueue< cds::gc::DHP, base_hook_item, traits_BasketQueue_disposer > BasketQueue_DHP_base; + + // DHP member hook + struct traits_BasketQueue_member : public traits_BasketQueue_disposer + { + typedef ci::basket_queue::member_hook< offsetof( member_hook_item, hMember ), ci::opt::gc < cds::gc::DHP > > hook; + }; + typedef ci::BasketQueue< cds::gc::DHP, member_hook_item, traits_BasketQueue_member >BasketQueue_DHP_member; + + /// DHP base hook + item counter + typedef ci::BasketQueue< cds::gc::DHP, base_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,ci::opt::hook< + ci::basket_queue::base_hook< ci::opt::gc > + > + ,co::item_counter< cds::atomicity::item_counter > + ,co::memory_model< co::v::relaxed_ordering > + >::type + > BasketQueue_DHP_base_ic; + + // DHP member hook + item counter + typedef ci::BasketQueue< cds::gc::DHP, member_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::hook< + ci::basket_queue::member_hook< + offsetof(basket_queue::member_hook_item, hMember), + ci::opt::gc + > + > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,co::item_counter< cds::atomicity::item_counter > + >::type + > BasketQueue_DHP_member_ic; + + // DHP base hook + stat + typedef ci::BasketQueue< cds::gc::DHP, base_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::hook< + ci::basket_queue::base_hook< ci::opt::gc > + > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,co::stat< ci::basket_queue::stat<> > + >::type + > BasketQueue_DHP_base_stat; + + // DHP member hook + stat + typedef ci::BasketQueue< cds::gc::DHP, member_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::hook< + ci::basket_queue::member_hook< + offsetof(basket_queue::member_hook_item, hMember), + ci::opt::gc + > + > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,co::stat< ci::basket_queue::stat<> > + >::type + > BasketQueue_DHP_member_stat; + + // DHP base hook + alignment + typedef ci::BasketQueue< cds::gc::DHP, base_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,ci::opt::hook< + ci::basket_queue::base_hook< ci::opt::gc > + > + ,co::alignment< 32 > + >::type + > BasketQueue_DHP_base_align; + + // DHP member hook + alignment + typedef ci::BasketQueue< cds::gc::DHP, member_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::hook< + ci::basket_queue::member_hook< + offsetof(basket_queue::member_hook_item, hMember), + ci::opt::gc + > + > + ,co::alignment< 32 > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + >::type + > BasketQueue_DHP_member_align; + + // DHP base hook + no alignment + typedef ci::BasketQueue< cds::gc::DHP, base_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::hook< + ci::basket_queue::base_hook< ci::opt::gc > + > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,co::alignment< co::no_special_alignment > + >::type + > BasketQueue_DHP_base_noalign; + + // DHP member hook + no alignment + typedef ci::BasketQueue< cds::gc::DHP, member_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,ci::opt::hook< + ci::basket_queue::member_hook< + offsetof(basket_queue::member_hook_item, hMember), + ci::opt::gc + > + > + ,co::alignment< co::no_special_alignment > + >::type + > BasketQueue_DHP_member_noalign; + + + // DHP base hook + cache alignment + typedef ci::BasketQueue< cds::gc::DHP, base_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::hook< + ci::basket_queue::base_hook< ci::opt::gc > + > + ,co::alignment< co::cache_line_alignment > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + >::type + > BasketQueue_DHP_base_cachealign; + + // DHP member hook + cache alignment + typedef ci::BasketQueue< cds::gc::DHP, member_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::hook< + ci::basket_queue::member_hook< + offsetof(basket_queue::member_hook_item, hMember), + ci::opt::gc + > + > + ,co::alignment< co::cache_line_alignment > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + >::type + > BasketQueue_DHP_member_cachealign; + } // namespace + + TEST(BasketQueue_DHP_base) + TEST(BasketQueue_DHP_member) + TEST(BasketQueue_DHP_base_ic) + TEST(BasketQueue_DHP_member_ic) + TEST(BasketQueue_DHP_base_stat) + TEST(BasketQueue_DHP_member_stat) + TEST(BasketQueue_DHP_base_align) + TEST(BasketQueue_DHP_member_align) + TEST(BasketQueue_DHP_base_noalign) + TEST(BasketQueue_DHP_member_noalign) + TEST(BasketQueue_DHP_base_cachealign) + TEST(BasketQueue_DHP_member_cachealign) +} diff --git a/tests/test-hdr/queue/hdr_intrusive_basketqueue_hp.cpp b/tests/test-hdr/queue/hdr_intrusive_basketqueue_hp.cpp index 40afd90d..f2e0242a 100644 --- a/tests/test-hdr/queue/hdr_intrusive_basketqueue_hp.cpp +++ b/tests/test-hdr/queue/hdr_intrusive_basketqueue_hp.cpp @@ -1,174 +1,185 @@ //$$CDS-header$$ #include "hdr_intrusive_msqueue.h" - -#include "hdr_intrusive_basketqueue_node.h" #include +#include namespace queue { #define TEST(X) void IntrusiveQueueHeaderTest::test_##X() { test_basket(); } namespace { - typedef ci::BasketQueue< cds::gc::HP, - basket_queue::base_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - > BasketQueue_HP_default; + typedef IntrusiveQueueHeaderTest::base_hook_item< ci::basket_queue::node > base_hook_item; + typedef IntrusiveQueueHeaderTest::member_hook_item< ci::basket_queue::node > member_hook_item; + + struct traits_BasketQueue_HP_default : public ci::basket_queue::traits + { + typedef IntrusiveQueueHeaderTest::faked_disposer disposer; + }; + typedef ci::BasketQueue< cds::gc::HP, base_hook_item, traits_BasketQueue_HP_default > BasketQueue_HP_default; /// HP + item counter - typedef ci::BasketQueue< cds::gc::HP, - basket_queue::base_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::item_counter< cds::atomicity::item_counter > - ,co::memory_model< co::v::sequential_consistent > - > BasketQueue_HP_default_ic; + struct traits_BasketQueue_HP_default_ic : public traits_BasketQueue_HP_default + { + typedef cds::atomicity::item_counter item_counter; + typedef co::v::sequential_consistent memory_model; + }; + typedef ci::BasketQueue< cds::gc::HP, base_hook_item, traits_BasketQueue_HP_default_ic > BasketQueue_HP_default_ic; /// HP + stat - typedef ci::BasketQueue< cds::gc::HP, - basket_queue::base_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::stat< ci::queue_stat<> > + typedef ci::BasketQueue< cds::gc::HP, base_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,co::stat< ci::basket_queue::stat<> > + >::type > BasketQueue_HP_default_stat; // HP base hook - typedef ci::BasketQueue< cds::gc::HP, - basket_queue::base_hook_item - ,ci::opt::hook< - ci::basket_queue::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - > BasketQueue_HP_base; + struct traits_BasketQueue_HP_base : public ci::basket_queue::traits + { + typedef IntrusiveQueueHeaderTest::faked_disposer disposer; + typedef ci::basket_queue::base_hook< ci::opt::gc > hook; + }; + typedef ci::BasketQueue< cds::gc::HP, base_hook_item, traits_BasketQueue_HP_base > BasketQueue_HP_base; // HP member hook - typedef ci::BasketQueue< cds::gc::HP, - basket_queue::member_hook_item - ,ci::opt::hook< - ci::basket_queue::member_hook< - offsetof(basket_queue::member_hook_item, hMember), - ci::opt::gc - > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - > BasketQueue_HP_member; + struct traits_BasketQueue_HP_member : public traits_BasketQueue_HP_base + { + typedef ci::basket_queue::member_hook < + offsetof( member_hook_item, hMember ), + ci::opt::gc < cds::gc::HP > + > hook; + + }; + typedef ci::BasketQueue< cds::gc::HP, member_hook_item, traits_BasketQueue_HP_member > BasketQueue_HP_member; /// HP base hook + item counter - typedef ci::BasketQueue< cds::gc::HP, - basket_queue::base_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::basket_queue::base_hook< ci::opt::gc > - > - ,co::item_counter< cds::atomicity::item_counter > - ,co::memory_model< co::v::relaxed_ordering > + typedef ci::BasketQueue< cds::gc::HP, base_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,ci::opt::hook< + ci::basket_queue::base_hook< ci::opt::gc > + > + ,co::item_counter< cds::atomicity::item_counter > + ,co::memory_model< co::v::relaxed_ordering > + >::type > BasketQueue_HP_base_ic; // HP member hook + item counter - typedef ci::BasketQueue< cds::gc::HP, - basket_queue::member_hook_item - ,ci::opt::hook< - ci::basket_queue::member_hook< - offsetof(basket_queue::member_hook_item, hMember), - ci::opt::gc + typedef ci::BasketQueue< cds::gc::HP, member_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::hook< + ci::basket_queue::member_hook< + offsetof(basket_queue::member_hook_item, hMember), + ci::opt::gc + > > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::item_counter< cds::atomicity::item_counter > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,co::item_counter< cds::atomicity::item_counter > + >::type > BasketQueue_HP_member_ic; // HP base hook + stat - typedef ci::BasketQueue< cds::gc::HP, - basket_queue::base_hook_item - ,ci::opt::hook< - ci::basket_queue::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::stat< ci::queue_stat<> > + typedef ci::BasketQueue< cds::gc::HP, base_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::hook< + ci::basket_queue::base_hook< ci::opt::gc > + > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,co::stat< ci::basket_queue::stat<> > + >::type > BasketQueue_HP_base_stat; // HP member hook + stat - typedef ci::BasketQueue< cds::gc::HP, - basket_queue::member_hook_item - ,ci::opt::hook< - ci::basket_queue::member_hook< - offsetof(basket_queue::member_hook_item, hMember), - ci::opt::gc + typedef ci::BasketQueue< cds::gc::HP, member_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::hook< + ci::basket_queue::member_hook< + offsetof(member_hook_item, hMember), + ci::opt::gc + > > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::stat< ci::queue_stat<> > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,co::stat< ci::basket_queue::stat<> > + >::type > BasketQueue_HP_member_stat; // HP base hook + alignment - typedef ci::BasketQueue< cds::gc::HP, - basket_queue::base_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::basket_queue::base_hook< ci::opt::gc > - > - ,co::alignment< 32 > + typedef ci::BasketQueue< cds::gc::HP, base_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,ci::opt::hook< + ci::basket_queue::base_hook< ci::opt::gc > + > + ,co::alignment< 32 > + >::type > BasketQueue_HP_base_align; // HP member hook + alignment - typedef ci::BasketQueue< cds::gc::HP, - basket_queue::member_hook_item - ,ci::opt::hook< - ci::basket_queue::member_hook< - offsetof(basket_queue::member_hook_item, hMember), - ci::opt::gc + typedef ci::BasketQueue< cds::gc::HP, member_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::hook< + ci::basket_queue::member_hook< + offsetof(member_hook_item, hMember), + ci::opt::gc + > > - > - ,co::alignment< 32 > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,co::alignment< 32 > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + >::type > BasketQueue_HP_member_align; // HP base hook + no alignment - typedef ci::BasketQueue< cds::gc::HP, - basket_queue::base_hook_item - ,ci::opt::hook< - ci::basket_queue::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::alignment< co::no_special_alignment > + typedef ci::BasketQueue< cds::gc::HP, base_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::hook< + ci::basket_queue::base_hook< ci::opt::gc > + > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,co::alignment< co::no_special_alignment > + >::type > BasketQueue_HP_base_noalign; // HP member hook + no alignment - typedef ci::BasketQueue< cds::gc::HP, - basket_queue::member_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::basket_queue::member_hook< - offsetof(basket_queue::member_hook_item, hMember), - ci::opt::gc + typedef ci::BasketQueue< cds::gc::HP, member_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,ci::opt::hook< + ci::basket_queue::member_hook< + offsetof(member_hook_item, hMember), + ci::opt::gc + > > - > - ,co::alignment< co::no_special_alignment > + ,co::alignment< co::no_special_alignment > + >::type > BasketQueue_HP_member_noalign; // HP base hook + cache alignment - typedef ci::BasketQueue< cds::gc::HP, - basket_queue::base_hook_item - ,ci::opt::hook< - ci::basket_queue::base_hook< ci::opt::gc > - > - ,co::alignment< co::cache_line_alignment > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + typedef ci::BasketQueue< cds::gc::HP, base_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::hook< + ci::basket_queue::base_hook< ci::opt::gc > + > + ,co::alignment< co::cache_line_alignment > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + >::type > BasketQueue_HP_base_cachealign; // HP member hook + cache alignment - typedef ci::BasketQueue< cds::gc::HP, - basket_queue::member_hook_item - ,ci::opt::hook< - ci::basket_queue::member_hook< - offsetof(basket_queue::member_hook_item, hMember), - ci::opt::gc + typedef ci::BasketQueue< cds::gc::HP, member_hook_item, + typename ci::basket_queue::make_traits< + ci::opt::hook< + ci::basket_queue::member_hook< + offsetof(member_hook_item, hMember), + ci::opt::gc + > > - > - ,co::alignment< co::cache_line_alignment > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,co::alignment< co::cache_line_alignment > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + >::type > BasketQueue_HP_member_cachealign; - - } + } // namespace TEST(BasketQueue_HP_default) TEST(BasketQueue_HP_default_ic) diff --git a/tests/test-hdr/queue/hdr_intrusive_basketqueue_hrc.cpp b/tests/test-hdr/queue/hdr_intrusive_basketqueue_hrc.cpp deleted file mode 100644 index 7796bcbb..00000000 --- a/tests/test-hdr/queue/hdr_intrusive_basketqueue_hrc.cpp +++ /dev/null @@ -1,59 +0,0 @@ -//$$CDS-header$$ - -#include "hdr_intrusive_msqueue.h" - -#include "hdr_intrusive_basketqueue_node.h" -#include - -namespace queue { - -#define TEST(X) void IntrusiveQueueHeaderTest::test_##X() { test_basket(); } - - namespace { - // HRC base hook - typedef ci::BasketQueue< cds::gc::HRC, - basket_queue::base_hook_item - ,ci::opt::hook< - ci::basket_queue::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - > BasketQueue_HRC_base; - - /// HRC base hook + item counter - typedef ci::BasketQueue< cds::gc::HRC, - basket_queue::base_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::basket_queue::base_hook< ci::opt::gc > - > - ,co::item_counter< cds::atomicity::item_counter > - ,co::memory_model< co::v::relaxed_ordering > - > BasketQueue_HRC_base_ic; - - // HRC base hook + stat - typedef ci::BasketQueue< cds::gc::HRC, - basket_queue::base_hook_item - ,ci::opt::hook< - ci::basket_queue::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::stat< ci::queue_stat<> > - > BasketQueue_HRC_base_stat; - - // HRC base hook + alignment - typedef ci::BasketQueue< cds::gc::HRC, - basket_queue::base_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::basket_queue::base_hook< ci::opt::gc > - > - ,co::alignment< 32 > - > BasketQueue_HRC_base_align; - - } - - TEST(BasketQueue_HRC_base) - TEST(BasketQueue_HRC_base_ic) - TEST(BasketQueue_HRC_base_stat) - TEST(BasketQueue_HRC_base_align) -} diff --git a/tests/test-hdr/queue/hdr_intrusive_basketqueue_node.h b/tests/test-hdr/queue/hdr_intrusive_basketqueue_node.h deleted file mode 100644 index 198ce6c8..00000000 --- a/tests/test-hdr/queue/hdr_intrusive_basketqueue_node.h +++ /dev/null @@ -1,39 +0,0 @@ -//$$CDS-header$$ - -#ifndef CDSTEST_HDR_TEST_INTRUSIVE_BASKET_QUEUE_NODE_H -#define CDSTEST_HDR_TEST_INTRUSIVE_BASKET_QUEUE_NODE_H - -#include - -namespace queue { - namespace ci = cds::intrusive; - namespace co = cds::opt; - - namespace basket_queue { - template - struct base_hook_item: public ci::basket_queue::node< GC > - { - int nVal; - int nDisposeCount; - - base_hook_item() - : nDisposeCount(0) - {} - }; - - template - struct member_hook_item - { - int nVal; - int nDisposeCount; - ci::basket_queue::node< GC > hMember; - - member_hook_item() - : nDisposeCount(0) - {} - }; - - } // namespace basket_queue -} // queue - -#endif // #ifndef CDSTEST_HDR_TEST_INTRUSIVE_BASKET_QUEUE_NODE_H diff --git a/tests/test-hdr/queue/hdr_intrusive_basketqueue_ptb.cpp b/tests/test-hdr/queue/hdr_intrusive_basketqueue_ptb.cpp deleted file mode 100644 index db4a1c3d..00000000 --- a/tests/test-hdr/queue/hdr_intrusive_basketqueue_ptb.cpp +++ /dev/null @@ -1,165 +0,0 @@ -//$$CDS-header$$ - -#include "hdr_intrusive_msqueue.h" - -#include "hdr_intrusive_basketqueue_node.h" -#include - -namespace queue { - -#define TEST(X) void IntrusiveQueueHeaderTest::test_##X() { test_basket(); } - - namespace { - // PTB base hook - typedef ci::BasketQueue< cds::gc::PTB, - basket_queue::base_hook_item - ,ci::opt::hook< - ci::basket_queue::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - > BasketQueue_PTB_base; - - // PTB member hook - typedef ci::BasketQueue< cds::gc::PTB, - basket_queue::member_hook_item - ,ci::opt::hook< - ci::basket_queue::member_hook< - offsetof(basket_queue::member_hook_item, hMember), - ci::opt::gc - > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - > BasketQueue_PTB_member; - - /// PTB base hook + item counter - typedef ci::BasketQueue< cds::gc::PTB, - basket_queue::base_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::basket_queue::base_hook< ci::opt::gc > - > - ,co::item_counter< cds::atomicity::item_counter > - ,co::memory_model< co::v::relaxed_ordering > - > BasketQueue_PTB_base_ic; - - // PTB member hook + item counter - typedef ci::BasketQueue< cds::gc::PTB, - basket_queue::member_hook_item - ,ci::opt::hook< - ci::basket_queue::member_hook< - offsetof(basket_queue::member_hook_item, hMember), - ci::opt::gc - > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::item_counter< cds::atomicity::item_counter > - > BasketQueue_PTB_member_ic; - - // PTB base hook + stat - typedef ci::BasketQueue< cds::gc::PTB, - basket_queue::base_hook_item - ,ci::opt::hook< - ci::basket_queue::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::stat< ci::queue_stat<> > - > BasketQueue_PTB_base_stat; - - // PTB member hook + stat - typedef ci::BasketQueue< cds::gc::PTB, - basket_queue::member_hook_item - ,ci::opt::hook< - ci::basket_queue::member_hook< - offsetof(basket_queue::member_hook_item, hMember), - ci::opt::gc - > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::stat< ci::queue_stat<> > - > BasketQueue_PTB_member_stat; - - // PTB base hook + alignment - typedef ci::BasketQueue< cds::gc::PTB, - basket_queue::base_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::basket_queue::base_hook< ci::opt::gc > - > - ,co::alignment< 32 > - > BasketQueue_PTB_base_align; - - // PTB member hook + alignment - typedef ci::BasketQueue< cds::gc::PTB, - basket_queue::member_hook_item - ,ci::opt::hook< - ci::basket_queue::member_hook< - offsetof(basket_queue::member_hook_item, hMember), - ci::opt::gc - > - > - ,co::alignment< 32 > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - > BasketQueue_PTB_member_align; - - // PTB base hook + no alignment - typedef ci::BasketQueue< cds::gc::PTB, - basket_queue::base_hook_item - ,ci::opt::hook< - ci::basket_queue::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::alignment< co::no_special_alignment > - > BasketQueue_PTB_base_noalign; - - // PTB member hook + no alignment - typedef ci::BasketQueue< cds::gc::PTB, - basket_queue::member_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::basket_queue::member_hook< - offsetof(basket_queue::member_hook_item, hMember), - ci::opt::gc - > - > - ,co::alignment< co::no_special_alignment > - > BasketQueue_PTB_member_noalign; - - - // PTB base hook + cache alignment - typedef ci::BasketQueue< cds::gc::PTB, - basket_queue::base_hook_item - ,ci::opt::hook< - ci::basket_queue::base_hook< ci::opt::gc > - > - ,co::alignment< co::cache_line_alignment > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - > BasketQueue_PTB_base_cachealign; - - // PTB member hook + cache alignment - typedef ci::BasketQueue< cds::gc::PTB, - basket_queue::member_hook_item - ,ci::opt::hook< - ci::basket_queue::member_hook< - offsetof(basket_queue::member_hook_item, hMember), - ci::opt::gc - > - > - ,co::alignment< co::cache_line_alignment > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - > BasketQueue_PTB_member_cachealign; - - } - - TEST(BasketQueue_PTB_base) - TEST(BasketQueue_PTB_member) - TEST(BasketQueue_PTB_base_ic) - TEST(BasketQueue_PTB_member_ic) - TEST(BasketQueue_PTB_base_stat) - TEST(BasketQueue_PTB_member_stat) - TEST(BasketQueue_PTB_base_align) - TEST(BasketQueue_PTB_member_align) - TEST(BasketQueue_PTB_base_noalign) - TEST(BasketQueue_PTB_member_noalign) - TEST(BasketQueue_PTB_base_cachealign) - TEST(BasketQueue_PTB_member_cachealign) -} diff --git a/tests/test-hdr/queue/hdr_intrusive_msqueue.h b/tests/test-hdr/queue/hdr_intrusive_msqueue.h index 3c73ec3d..05c6ac46 100644 --- a/tests/test-hdr/queue/hdr_intrusive_msqueue.h +++ b/tests/test-hdr/queue/hdr_intrusive_msqueue.h @@ -367,22 +367,18 @@ namespace queue { void test_BasketQueue_HP_member_noalign(); void test_BasketQueue_HP_base_cachealign(); void test_BasketQueue_HP_member_cachealign(); - void test_BasketQueue_HRC_base(); - void test_BasketQueue_HRC_base_ic(); - void test_BasketQueue_HRC_base_stat(); - void test_BasketQueue_HRC_base_align(); - void test_BasketQueue_PTB_base(); - void test_BasketQueue_PTB_member(); - void test_BasketQueue_PTB_base_ic(); - void test_BasketQueue_PTB_member_ic(); - void test_BasketQueue_PTB_base_stat(); - void test_BasketQueue_PTB_member_stat(); - void test_BasketQueue_PTB_base_align(); - void test_BasketQueue_PTB_member_align(); - void test_BasketQueue_PTB_base_noalign(); - void test_BasketQueue_PTB_member_noalign(); - void test_BasketQueue_PTB_base_cachealign(); - void test_BasketQueue_PTB_member_cachealign(); + void test_BasketQueue_DHP_base(); + void test_BasketQueue_DHP_member(); + void test_BasketQueue_DHP_base_ic(); + void test_BasketQueue_DHP_member_ic(); + void test_BasketQueue_DHP_base_stat(); + void test_BasketQueue_DHP_member_stat(); + void test_BasketQueue_DHP_base_align(); + void test_BasketQueue_DHP_member_align(); + void test_BasketQueue_DHP_base_noalign(); + void test_BasketQueue_DHP_member_noalign(); + void test_BasketQueue_DHP_base_cachealign(); + void test_BasketQueue_DHP_member_cachealign(); void test_TsigasCycleQueue_stat(); void test_TsigasCycleQueue_stat_ic(); @@ -494,22 +490,18 @@ namespace queue { CPPUNIT_TEST(test_BasketQueue_HP_member_noalign) CPPUNIT_TEST(test_BasketQueue_HP_base_cachealign) CPPUNIT_TEST(test_BasketQueue_HP_member_cachealign) - CPPUNIT_TEST(test_BasketQueue_HRC_base) - CPPUNIT_TEST(test_BasketQueue_HRC_base_ic) - CPPUNIT_TEST(test_BasketQueue_HRC_base_stat) - CPPUNIT_TEST(test_BasketQueue_HRC_base_align) - CPPUNIT_TEST(test_BasketQueue_PTB_base) - CPPUNIT_TEST(test_BasketQueue_PTB_member) - CPPUNIT_TEST(test_BasketQueue_PTB_base_ic) - CPPUNIT_TEST(test_BasketQueue_PTB_member_ic) - CPPUNIT_TEST(test_BasketQueue_PTB_base_stat) - CPPUNIT_TEST(test_BasketQueue_PTB_member_stat) - CPPUNIT_TEST(test_BasketQueue_PTB_base_align) - CPPUNIT_TEST(test_BasketQueue_PTB_member_align) - CPPUNIT_TEST(test_BasketQueue_PTB_base_noalign) - CPPUNIT_TEST(test_BasketQueue_PTB_member_noalign) - CPPUNIT_TEST(test_BasketQueue_PTB_base_cachealign) - CPPUNIT_TEST(test_BasketQueue_PTB_member_cachealign) + CPPUNIT_TEST(test_BasketQueue_DHP_base) + CPPUNIT_TEST(test_BasketQueue_DHP_member) + CPPUNIT_TEST(test_BasketQueue_DHP_base_ic) + CPPUNIT_TEST(test_BasketQueue_DHP_member_ic) + CPPUNIT_TEST(test_BasketQueue_DHP_base_stat) + CPPUNIT_TEST(test_BasketQueue_DHP_member_stat) + CPPUNIT_TEST(test_BasketQueue_DHP_base_align) + CPPUNIT_TEST(test_BasketQueue_DHP_member_align) + CPPUNIT_TEST(test_BasketQueue_DHP_base_noalign) + CPPUNIT_TEST(test_BasketQueue_DHP_member_noalign) + CPPUNIT_TEST(test_BasketQueue_DHP_base_cachealign) + CPPUNIT_TEST(test_BasketQueue_DHP_member_cachealign) CPPUNIT_TEST(test_TsigasCycleQueue_stat) CPPUNIT_TEST(test_TsigasCycleQueue_stat_ic) diff --git a/tests/test-hdr/queue/hdr_queue.h b/tests/test-hdr/queue/hdr_queue.h index c48db253..db33b922 100644 --- a/tests/test-hdr/queue/hdr_queue.h +++ b/tests/test-hdr/queue/hdr_queue.h @@ -161,39 +161,6 @@ namespace queue { void OptimisticQueue_PTB_Counted_relax_align(); void OptimisticQueue_PTB_Counted_seqcst_align(); - void BasketQueue_HP(); - void BasketQueue_HP_relax(); - void BasketQueue_HP_seqcst(); - void BasketQueue_HP_relax_align(); - void BasketQueue_HP_seqcst_align(); - void BasketQueue_HP_Counted(); - void BasketQueue_HP_Counted_relax(); - void BasketQueue_HP_Counted_seqcst(); - void BasketQueue_HP_Counted_relax_align(); - void BasketQueue_HP_Counted_seqcst_align(); - - void BasketQueue_HRC(); - void BasketQueue_HRC_relax(); - void BasketQueue_HRC_seqcst(); - void BasketQueue_HRC_relax_align(); - void BasketQueue_HRC_seqcst_align(); - void BasketQueue_HRC_Counted(); - void BasketQueue_HRC_Counted_relax(); - void BasketQueue_HRC_Counted_seqcst(); - void BasketQueue_HRC_Counted_relax_align(); - void BasketQueue_HRC_Counted_seqcst_align(); - - void BasketQueue_PTB(); - void BasketQueue_PTB_relax(); - void BasketQueue_PTB_seqcst(); - void BasketQueue_PTB_relax_align(); - void BasketQueue_PTB_seqcst_align(); - void BasketQueue_PTB_Counted(); - void BasketQueue_PTB_Counted_relax(); - void BasketQueue_PTB_Counted_seqcst(); - void BasketQueue_PTB_Counted_relax_align(); - void BasketQueue_PTB_Counted_seqcst_align(); - void FCQueue_deque(); void FCQueue_deque_elimination(); void FCQueue_deque_mutex(); @@ -232,39 +199,6 @@ namespace queue { CPPUNIT_TEST(OptimisticQueue_PTB_Counted_relax_align); CPPUNIT_TEST(OptimisticQueue_PTB_Counted_seqcst_align); - CPPUNIT_TEST(BasketQueue_HP); - CPPUNIT_TEST(BasketQueue_HP_relax); - CPPUNIT_TEST(BasketQueue_HP_seqcst); - CPPUNIT_TEST(BasketQueue_HP_relax_align); - CPPUNIT_TEST(BasketQueue_HP_seqcst_align); - CPPUNIT_TEST(BasketQueue_HP_Counted); - CPPUNIT_TEST(BasketQueue_HP_Counted_relax); - CPPUNIT_TEST(BasketQueue_HP_Counted_seqcst); - CPPUNIT_TEST(BasketQueue_HP_Counted_relax_align); - CPPUNIT_TEST(BasketQueue_HP_Counted_seqcst_align); - - CPPUNIT_TEST(BasketQueue_HRC); - CPPUNIT_TEST(BasketQueue_HRC_relax); - CPPUNIT_TEST(BasketQueue_HRC_seqcst); - CPPUNIT_TEST(BasketQueue_HRC_relax_align); - CPPUNIT_TEST(BasketQueue_HRC_seqcst_align); - CPPUNIT_TEST(BasketQueue_HRC_Counted); - CPPUNIT_TEST(BasketQueue_HRC_Counted_relax); - CPPUNIT_TEST(BasketQueue_HRC_Counted_seqcst); - CPPUNIT_TEST(BasketQueue_HRC_Counted_relax_align); - CPPUNIT_TEST(BasketQueue_HRC_Counted_seqcst_align); - - CPPUNIT_TEST(BasketQueue_PTB); - CPPUNIT_TEST(BasketQueue_PTB_relax); - CPPUNIT_TEST(BasketQueue_PTB_seqcst); - CPPUNIT_TEST(BasketQueue_PTB_relax_align); - CPPUNIT_TEST(BasketQueue_PTB_seqcst_align); - CPPUNIT_TEST(BasketQueue_PTB_Counted); - CPPUNIT_TEST(BasketQueue_PTB_Counted_relax); - CPPUNIT_TEST(BasketQueue_PTB_Counted_seqcst); - CPPUNIT_TEST(BasketQueue_PTB_Counted_relax_align); - CPPUNIT_TEST(BasketQueue_PTB_Counted_seqcst_align); - CPPUNIT_TEST(FCQueue_deque) CPPUNIT_TEST(FCQueue_deque_elimination) CPPUNIT_TEST(FCQueue_deque_mutex) diff --git a/tests/test-hdr/queue/hdr_queue_new.h b/tests/test-hdr/queue/hdr_queue_new.h index cde550a8..e10b82d4 100644 --- a/tests/test-hdr/queue/hdr_queue_new.h +++ b/tests/test-hdr/queue/hdr_queue_new.h @@ -266,7 +266,7 @@ namespace queue { void OptimisticQueue_DHP_Counted_seqcst(); void OptimisticQueue_DHP_Counted_relax_align(); void OptimisticQueue_DHP_Counted_seqcst_align(); - +*/ void BasketQueue_HP(); void BasketQueue_HP_relax(); void BasketQueue_HP_seqcst(); @@ -288,7 +288,7 @@ namespace queue { void BasketQueue_DHP_Counted_seqcst(); void BasketQueue_DHP_Counted_relax_align(); void BasketQueue_DHP_Counted_seqcst_align(); - +/* void FCQueue_deque(); void FCQueue_deque_elimination(); void FCQueue_deque_mutex(); @@ -371,7 +371,7 @@ namespace queue { CPPUNIT_TEST(OptimisticQueue_DHP_Counted_seqcst); CPPUNIT_TEST(OptimisticQueue_DHP_Counted_relax_align); CPPUNIT_TEST(OptimisticQueue_DHP_Counted_seqcst_align); - +*/ CPPUNIT_TEST(BasketQueue_HP); CPPUNIT_TEST(BasketQueue_HP_relax); CPPUNIT_TEST(BasketQueue_HP_seqcst); @@ -393,7 +393,7 @@ namespace queue { CPPUNIT_TEST(BasketQueue_DHP_Counted_seqcst); CPPUNIT_TEST(BasketQueue_DHP_Counted_relax_align); CPPUNIT_TEST(BasketQueue_DHP_Counted_seqcst_align); - +/* CPPUNIT_TEST(FCQueue_deque) CPPUNIT_TEST(FCQueue_deque_elimination) CPPUNIT_TEST(FCQueue_deque_mutex) diff --git a/tests/unit/queue/intrusive_queue_defs.h b/tests/unit/queue/intrusive_queue_defs.h index 8dc845e3..03b96c32 100644 --- a/tests/unit/queue/intrusive_queue_defs.h +++ b/tests/unit/queue/intrusive_queue_defs.h @@ -74,28 +74,20 @@ TEST_CASE(BasketQueue_HP_ic, cds::intrusive::basket_queue::node< cds::gc::HP > ) \ TEST_CASE(BasketQueue_HP_stat, cds::intrusive::basket_queue::node< cds::gc::HP > ) \ TEST_CASE(BasketQueue_HP_seqcst, cds::intrusive::basket_queue::node< cds::gc::HP > ) \ - TEST_CASE(BasketQueue_HRC, cds::intrusive::basket_queue::node< cds::gc::HRC > ) \ - TEST_CASE(BasketQueue_HRC_ic, cds::intrusive::basket_queue::node< cds::gc::HRC > ) \ - TEST_CASE(BasketQueue_HRC_stat, cds::intrusive::basket_queue::node< cds::gc::HRC > ) \ - TEST_CASE(BasketQueue_HRC_seqcst, cds::intrusive::basket_queue::node< cds::gc::HRC > ) \ - TEST_CASE(BasketQueue_PTB, cds::intrusive::basket_queue::node< cds::gc::PTB > ) \ - TEST_CASE(BasketQueue_PTB_ic, cds::intrusive::basket_queue::node< cds::gc::PTB > ) \ - TEST_CASE(BasketQueue_PTB_stat, cds::intrusive::basket_queue::node< cds::gc::PTB > ) \ - TEST_CASE(BasketQueue_PTB_seqcst, cds::intrusive::basket_queue::node< cds::gc::PTB > ) + TEST_CASE(BasketQueue_DHP, cds::intrusive::basket_queue::node< cds::gc::DHP > ) \ + TEST_CASE(BasketQueue_DHP_ic, cds::intrusive::basket_queue::node< cds::gc::DHP > ) \ + TEST_CASE(BasketQueue_DHP_stat, cds::intrusive::basket_queue::node< cds::gc::DHP > ) \ + TEST_CASE(BasketQueue_DHP_seqcst, cds::intrusive::basket_queue::node< cds::gc::DHP > ) #define CDSUNIT_TEST_BasketQueue \ CPPUNIT_TEST(BasketQueue_HP) \ CPPUNIT_TEST(BasketQueue_HP_ic) \ CPPUNIT_TEST(BasketQueue_HP_stat) \ CPPUNIT_TEST(BasketQueue_HP_seqcst) \ - /*CPPUNIT_TEST(BasketQueue_HRC)*/ \ - /*CPPUNIT_TEST(BasketQueue_HRC_ic)*/ \ - /*CPPUNIT_TEST(BasketQueue_HRC_stat)*/ \ - /*CPPUNIT_TEST(BasketQueue_HRC_seqcst)*/ \ - CPPUNIT_TEST(BasketQueue_PTB) \ - CPPUNIT_TEST(BasketQueue_PTB_ic) \ - CPPUNIT_TEST(BasketQueue_PTB_stat) \ - CPPUNIT_TEST(BasketQueue_PTB_seqcst) + CPPUNIT_TEST(BasketQueue_DHP) \ + CPPUNIT_TEST(BasketQueue_DHP_ic) \ + CPPUNIT_TEST(BasketQueue_DHP_stat) \ + CPPUNIT_TEST(BasketQueue_DHP_seqcst) // TsigasCycleQueue #define CDSUNIT_DECLARE_TsigasCycleQueue \ diff --git a/tests/unit/queue/intrusive_queue_type.h b/tests/unit/queue/intrusive_queue_type.h index c5527b88..f5c7e612 100644 --- a/tests/unit/queue/intrusive_queue_type.h +++ b/tests/unit/queue/intrusive_queue_type.h @@ -290,64 +290,69 @@ namespace queue { }; // BasketQueue - typedef cds::intrusive::BasketQueue< cds::gc::HP, T - ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > > - > BasketQueue_HP; - - typedef cds::intrusive::BasketQueue > > - ,cds::opt::memory_model< cds::opt::v::sequential_consistent > - > BasketQueue_HP_seqcst; - - typedef cds::intrusive::BasketQueue< cds::gc::HRC, T - ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HRC > > > - > BasketQueue_HRC; + struct traits_BasketQueue_HP : public + cds::intrusive::basket_queue::make_traits < + cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > > + > ::type + {}; + typedef cds::intrusive::BasketQueue< cds::gc::HP, T, traits_BasketQueue_HP > BasketQueue_HP; - typedef cds::intrusive::BasketQueue< cds::gc::HRC, T - ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HRC > > > - ,cds::opt::memory_model< cds::opt::v::sequential_consistent > - > BasketQueue_HRC_seqcst; + struct traits_BasketQueue_HP_seqcst: public + cds::intrusive::basket_queue::make_traits < + cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > > + , cds::opt::memory_model< cds::opt::v::sequential_consistent > + > ::type + {}; + typedef cds::intrusive::BasketQueue BasketQueue_HP_seqcst; - typedef cds::intrusive::BasketQueue< cds::gc::PTB, T - ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::PTB > > > - > BasketQueue_PTB; + struct traits_BasketQueue_DHP : public + cds::intrusive::basket_queue::make_traits < + cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::DHP > > > + > ::type + {}; + typedef cds::intrusive::BasketQueue< cds::gc::DHP, T, traits_BasketQueue_DHP > BasketQueue_DHP; - typedef cds::intrusive::BasketQueue< cds::gc::PTB, T - ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::PTB > > > - ,cds::opt::memory_model< cds::opt::v::sequential_consistent > - > BasketQueue_PTB_seqcst; + struct traits_BasketQueue_DHP_seqcst: public + cds::intrusive::basket_queue::make_traits < + cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::DHP > > > + , cds::opt::memory_model< cds::opt::v::sequential_consistent > + > ::type + {}; + typedef cds::intrusive::BasketQueue< cds::gc::DHP, T, traits_BasketQueue_DHP_seqcst > BasketQueue_DHP_seqcst; // BasketQueue + item counter - typedef cds::intrusive::BasketQueue< cds::gc::HP, T - ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > > - ,cds::opt::item_counter< cds::atomicity::item_counter > - > BasketQueue_HP_ic; - - typedef cds::intrusive::BasketQueue< cds::gc::HRC, T - ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HRC > > > - ,cds::opt::item_counter< cds::atomicity::item_counter > - > BasketQueue_HRC_ic; + struct traits_BasketQueue_HP_ic : public + cds::intrusive::basket_queue::make_traits < + cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > > + ,cds::opt::item_counter< cds::atomicity::item_counter > + > ::type + {}; + typedef cds::intrusive::BasketQueue< cds::gc::HP, T, traits_BasketQueue_HP_ic > BasketQueue_HP_ic; - typedef cds::intrusive::BasketQueue< cds::gc::PTB, T - ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::PTB > > > - ,cds::opt::item_counter< cds::atomicity::item_counter > - > BasketQueue_PTB_ic; + struct traits_BasketQueue_DHP_ic : public + cds::intrusive::basket_queue::make_traits < + cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::DHP > > > + ,cds::opt::item_counter< cds::atomicity::item_counter > + > ::type + {}; + typedef cds::intrusive::BasketQueue< cds::gc::DHP, T, traits_BasketQueue_DHP_ic > BasketQueue_DHP_ic; // BasketQueue + stat - typedef cds::intrusive::BasketQueue< cds::gc::HP, T - ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > > - ,cds::opt::stat< cds::intrusive::queue_stat<> > - > BasketQueue_HP_stat; - - typedef cds::intrusive::BasketQueue< cds::gc::HRC, T - ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HRC > > > - ,cds::opt::stat< cds::intrusive::queue_stat<> > - > BasketQueue_HRC_stat; + struct traits_BasketQueue_HP_stat : public + cds::intrusive::basket_queue::make_traits < + cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > > + , cds::opt::stat< cds::intrusive::basket_queue::stat<> > + > ::type + {}; + typedef cds::intrusive::BasketQueue< cds::gc::HP, T, traits_BasketQueue_HP_stat > BasketQueue_HP_stat; - typedef cds::intrusive::BasketQueue< cds::gc::PTB, T - ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::PTB > > > - ,cds::opt::stat< cds::intrusive::queue_stat<> > - > BasketQueue_PTB_stat; + struct traits_BasketQueue_DHP_stat : public + cds::intrusive::basket_queue::make_traits < + cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::DHP > > > + , cds::opt::stat< cds::intrusive::basket_queue::stat<> > + > ::type + {}; + typedef cds::intrusive::BasketQueue< cds::gc::DHP, T, traits_BasketQueue_DHP_stat > BasketQueue_DHP_stat; // FCQueue class traits_FCQueue_delay2: @@ -429,23 +434,24 @@ namespace std { // cds::intrusive::queue_stat template - static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::queue_stat const& s) + static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::basket_queue::stat const& s) { return o << "\tStatistics:\n" - << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n" - << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n" - << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n" - << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n" - << "\t\tAdvance tail error: " << s.m_AdvanceTailError.get() << "\n" - << "\t\t Bad tail: " << s.m_BadTail.get() << "\n"; + << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n" + << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n" + << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n" + << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n" + << "\t\t Advance tail error: " << s.m_AdvanceTailError.get() << "\n" + << "\t\t Bad tail: " << s.m_BadTail.get() << "\n" + << "\t\tAdd basket attempts: " << s.m_TryAddBasket.get() << "\n" + << "\t\t Add basket success: " << s.m_AddBasketCount.get() << "\n"; } - static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::queue_dummy_stat const& s) + static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::basket_queue::empty_stat const& s) { return o; } - template static inline std::ostream& operator <<( std::ostream& o, cds::intrusive::msqueue::stat const& s ) { diff --git a/tests/unit/queue/queue_defs.h b/tests/unit/queue/queue_defs.h index 6b088c9d..29c1b8f5 100644 --- a/tests/unit/queue/queue_defs.h +++ b/tests/unit/queue/queue_defs.h @@ -87,16 +87,11 @@ TEST_CASE( BasketQueue_HP_seqcst, ITEM_TYPE ) \ TEST_CASE( BasketQueue_HP_ic, ITEM_TYPE ) \ TEST_CASE( BasketQueue_HP_stat, ITEM_TYPE ) \ - TEST_CASE( BasketQueue_HRC, ITEM_TYPE ) \ - TEST_CASE( BasketQueue_HRC_michaelAlloc, ITEM_TYPE ) \ - TEST_CASE( BasketQueue_HRC_seqcst, ITEM_TYPE ) \ - TEST_CASE( BasketQueue_HRC_ic, ITEM_TYPE ) \ - TEST_CASE( BasketQueue_HRC_stat, ITEM_TYPE ) \ - TEST_CASE( BasketQueue_PTB, ITEM_TYPE ) \ - TEST_CASE( BasketQueue_PTB_michaelAlloc, ITEM_TYPE ) \ - TEST_CASE( BasketQueue_PTB_seqcst, ITEM_TYPE ) \ - TEST_CASE( BasketQueue_PTB_ic, ITEM_TYPE ) \ - TEST_CASE( BasketQueue_PTB_stat, ITEM_TYPE ) + TEST_CASE( BasketQueue_DHP, ITEM_TYPE ) \ + TEST_CASE( BasketQueue_DHP_michaelAlloc, ITEM_TYPE ) \ + TEST_CASE( BasketQueue_DHP_seqcst, ITEM_TYPE ) \ + TEST_CASE( BasketQueue_DHP_ic, ITEM_TYPE ) \ + TEST_CASE( BasketQueue_DHP_stat, ITEM_TYPE ) #define CDSUNIT_TEST_BasketQueue \ CPPUNIT_TEST(BasketQueue_HP) \ @@ -104,16 +99,11 @@ CPPUNIT_TEST(BasketQueue_HP_seqcst) \ CPPUNIT_TEST(BasketQueue_HP_ic) \ CPPUNIT_TEST(BasketQueue_HP_stat) \ - CPPUNIT_TEST(BasketQueue_HRC) \ - CPPUNIT_TEST(BasketQueue_HRC_michaelAlloc) \ - CPPUNIT_TEST(BasketQueue_HRC_seqcst) \ - CPPUNIT_TEST(BasketQueue_HRC_ic) \ - CPPUNIT_TEST(BasketQueue_HRC_stat) \ - CPPUNIT_TEST(BasketQueue_PTB) \ - CPPUNIT_TEST(BasketQueue_PTB_michaelAlloc) \ - CPPUNIT_TEST(BasketQueue_PTB_seqcst) \ - CPPUNIT_TEST(BasketQueue_PTB_ic) \ - CPPUNIT_TEST(BasketQueue_PTB_stat) + CPPUNIT_TEST(BasketQueue_DHP) \ + CPPUNIT_TEST(BasketQueue_DHP_michaelAlloc) \ + CPPUNIT_TEST(BasketQueue_DHP_seqcst) \ + CPPUNIT_TEST(BasketQueue_DHP_ic) \ + CPPUNIT_TEST(BasketQueue_DHP_stat) // FCQueue diff --git a/tests/unit/queue/queue_type.h b/tests/unit/queue/queue_type.h index 13b561c4..64f92b93 100644 --- a/tests/unit/queue/queue_type.h +++ b/tests/unit/queue/queue_type.h @@ -355,79 +355,37 @@ namespace queue { }; // BasketQueue - typedef cds::container::BasketQueue< - cds::gc::HP , Value - > BasketQueue_HP; - typedef cds::container::BasketQueue< - cds::gc::HP , Value - ,cds::opt::allocator< memory::MichaelAllocator > - > BasketQueue_HP_michaelAlloc; - - typedef cds::container::BasketQueue< - cds::gc::HP, Value - ,cds::opt::memory_model< cds::opt::v::sequential_consistent > - > BasketQueue_HP_seqcst; - - typedef cds::container::BasketQueue< cds::gc::HRC, - Value - > BasketQueue_HRC; - - typedef cds::container::BasketQueue< cds::gc::HRC, - Value - ,cds::opt::allocator< memory::MichaelAllocator > - > BasketQueue_HRC_michaelAlloc; - - typedef cds::container::BasketQueue< cds::gc::HRC, - Value - ,cds::opt::memory_model< cds::opt::v::sequential_consistent > - > BasketQueue_HRC_seqcst; + typedef cds::container::BasketQueue< cds::gc::HP , Value > BasketQueue_HP; + typedef cds::container::BasketQueue< cds::gc::DHP, Value > BasketQueue_DHP; - typedef cds::container::BasketQueue< cds::gc::PTB, - Value - > BasketQueue_PTB; - - typedef cds::container::BasketQueue< cds::gc::PTB, - Value - ,cds::opt::allocator< memory::MichaelAllocator > - > BasketQueue_PTB_michaelAlloc; - - typedef cds::container::BasketQueue< cds::gc::PTB, - Value - ,cds::opt::memory_model< cds::opt::v::sequential_consistent > - > BasketQueue_PTB_seqcst; - - // BasketQueue + item counter - typedef cds::container::BasketQueue< cds::gc::HP, - Value - ,cds::opt::item_counter< cds::atomicity::item_counter > - > BasketQueue_HP_ic; - - typedef cds::container::BasketQueue< cds::gc::HRC, - Value - ,cds::opt::item_counter< cds::atomicity::item_counter > - > BasketQueue_HRC_ic; - - typedef cds::container::BasketQueue< cds::gc::PTB, - Value - ,cds::opt::item_counter< cds::atomicity::item_counter > - > BasketQueue_PTB_ic; + struct traits_BasketQueue_michaelAlloc : public cds::container::basket_queue::traits + { + typedef memory::MichaelAllocator allocator; + }; + typedef cds::container::BasketQueue< cds::gc::HP, Value, traits_BasketQueue_michaelAlloc > BasketQueue_HP_michaelAlloc; + typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_michaelAlloc > BasketQueue_DHP_michaelAlloc; - // BasketQueue + stat - typedef cds::container::BasketQueue< cds::gc::HP, - Value - ,cds::opt::stat< cds::intrusive::queue_stat<> > - > BasketQueue_HP_stat; + struct traits_BasketQueue_seqcst : public cds::container::basket_queue::traits + { + typedef cds::opt::v::sequential_consistent mamory_model; + }; + typedef cds::container::BasketQueue< cds::gc::HP, Value, traits_BasketQueue_seqcst > BasketQueue_HP_seqcst; + typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_seqcst > BasketQueue_DHP_seqcst; - typedef cds::container::BasketQueue< cds::gc::HRC, - Value - ,cds::opt::stat< cds::intrusive::queue_stat<> > - > BasketQueue_HRC_stat; + struct traits_BasketQueue_ic : public cds::container::basket_queue::traits + { + typedef cds::atomicity::item_counter item_counter; + }; + typedef cds::container::BasketQueue< cds::gc::HP, Value, traits_BasketQueue_ic >BasketQueue_HP_ic; + typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_ic >BasketQueue_DHP_ic; - typedef cds::container::BasketQueue< cds::gc::PTB, - Value - ,cds::opt::stat< cds::intrusive::queue_stat<> > - > BasketQueue_PTB_stat; + struct traits_BasketQueue_stat : public cds::container::basket_queue::traits + { + typedef cds::container::basket_queue::stat<> stat; + }; + typedef cds::container::BasketQueue< cds::gc::HP, Value, traits_BasketQueue_stat > BasketQueue_HP_stat; + typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_stat > BasketQueue_DHP_stat; // RWQueue @@ -562,18 +520,20 @@ namespace std { // cds::intrusive::queue_stat template - static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::queue_stat const& s) + static inline std::ostream& operator <<(std::ostream& o, cds::container::basket_queue::stat const& s) { return o << "\tStatistics:\n" - << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n" - << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n" - << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n" - << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n" - << "\t\tAdvance tail error: " << s.m_AdvanceTailError.get() << "\n" - << "\t\t Bad tail: " << s.m_BadTail.get() << "\n"; + << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n" + << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n" + << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n" + << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n" + << "\t\t Advance tail error: " << s.m_AdvanceTailError.get() << "\n" + << "\t\t Bad tail: " << s.m_BadTail.get() << "\n" + << "\t\tAdd basket attempts: " << s.m_TryAddBasket.get() << "\n" + << "\t\t Add basket success: " << s.m_AddBasketCount.get() << "\n"; } - static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::queue_dummy_stat const& s) + static inline std::ostream& operator <<(std::ostream& o, cds::container::basket_queue::empty_stat const& s) { return o; }