From 2c0a92b4d21d563c2f102c561704ae36777a0e52 Mon Sep 17 00:00:00 2001 From: khizmax Date: Wed, 8 Oct 2014 10:48:32 +0400 Subject: [PATCH] intrusive::OptimisticQueue refactoring --- cds/intrusive/msqueue.h | 5 +- cds/intrusive/optimistic_queue.h | 364 ++++++++++-------- projects/Win/vc12/hdr-test-queue.vcxproj | 2 +- .../Win/vc12/hdr-test-queue.vcxproj.filters | 6 +- projects/source.test-hdr.offsetof.mk | 2 +- tests/test-hdr/queue/hdr_intrusive_msqueue.h | 48 +-- .../hdr_intrusive_optimisticqueue_dhp.cpp | 186 +++++++++ .../hdr_intrusive_optimisticqueue_hp.cpp | 241 ++++++------ .../hdr_intrusive_optimisticqueue_ptb.cpp | 187 --------- tests/unit/queue/intrusive_queue_defs.h | 16 +- tests/unit/queue/intrusive_queue_type.h | 85 ++-- 11 files changed, 609 insertions(+), 533 deletions(-) create mode 100644 tests/test-hdr/queue/hdr_intrusive_optimisticqueue_dhp.cpp delete mode 100644 tests/test-hdr/queue/hdr_intrusive_optimisticqueue_ptb.cpp diff --git a/cds/intrusive/msqueue.h b/cds/intrusive/msqueue.h index 164ef2ca..0683754d 100644 --- a/cds/intrusive/msqueue.h +++ b/cds/intrusive/msqueue.h @@ -171,7 +171,6 @@ namespace cds { namespace intrusive { /// Metafunction converting option list to \p msqueue::traits /** - This is a wrapper for cds::opt::make_options< type_traits, Options...> Supported \p Options are: - opt::hook - hook used. Possible hooks are: \p msqueue::base_hook, \p msqueue::member_hook, \p msqueue::traits_hook. @@ -211,8 +210,6 @@ namespace cds { namespace intrusive { >::type type; # endif }; - - } // namespace msqueue /// Michael & Scott's intrusive lock-free queue @@ -314,7 +311,7 @@ namespace cds { namespace intrusive { { public: typedef GC gc; ///< Garbage collector - typedef T value_type; ///< type of value stored in the queue + typedef T value_type; ///< type of value to be stored in the queue typedef Traits traits; ///< Queue traits typedef typename traits::hook hook; ///< hook type diff --git a/cds/intrusive/optimistic_queue.h b/cds/intrusive/optimistic_queue.h index cba41218..12ab10ba 100644 --- a/cds/intrusive/optimistic_queue.h +++ b/cds/intrusive/optimistic_queue.h @@ -4,16 +4,13 @@ #define __CDS_INTRUSIVE_OPTIMISTIC_QUEUE_H #include -#include // ref #include #include #include -#include -#include namespace cds { namespace intrusive { - /// Optimistic queue related definitions + /// OptimisticQueue related definitions /** @ingroup cds_intrusive_helper */ namespace optimistic_queue { @@ -64,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... > @@ -72,12 +69,12 @@ namespace cds { namespace intrusive { /// Member hook /** - \p MemberOffset defines offset in bytes of \ref node member into your structure. + \p MemberOffset specifies offset in bytes of \ref node member into your structure. Use \p offsetof macro to define \p MemberOffset \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... > @@ -94,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... > @@ -151,36 +148,59 @@ namespace cds { namespace intrusive { /// OptimisticQueue internal statistics. May be used for debugging or profiling /** Template argument \p Counter defines type of counter. - Default is cds::atomicity::event_counter, that is weak, i.e. it is not guaranteed + 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 cds::atomicity::item_counter, + You may use stronger type of counter like as \p cds::atomicity::item_counter, or even integral type, for example, \p int. - - The class extends intrusive::queue_stat interface for OptimisticQueue. */ template - struct stat: public cds::intrusive::queue_stat + struct stat { - //@cond - typedef cds::intrusive::queue_stat base_class; - typedef typename base_class::counter_type counter_type; - //@endcond - - counter_type m_FixListCount ; ///< Count of fix list event - + 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_FixListCount; ///< Count of fix list event + + /// 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 fix list event void onFixList() { ++m_FixListCount; } //@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_FixListCount.reset(); } stat& operator +=( stat const& s ) { - base_class::operator +=( s ); + 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_FixListCount += s.m_FixListCount.get(); return *this; } @@ -188,64 +208,143 @@ namespace cds { namespace intrusive { }; /// Dummy OptimisticQueue statistics - no counting is performed. Support interface like \ref optimistic_queue::stat - struct dummy_stat: public cds::intrusive::queue_dummy_stat + struct empty_stat { //@cond + void onEnqueue() {} + void onDequeue() {} + void onEnqueueRace() {} + void onDequeueRace() {} + void onAdvanceTailFailed() {} + void onBadTail() {} void onFixList() {} void reset() {} - dummy_stat& operator +=( dummy_stat const& ) + empty_stat& operator +=( empty_stat const& ) { return *this; } //@endcond }; + /// OptimisticQueue default type traits + struct traits + { + /// Back-off strategy + typedef cds::backoff::empty back_off; + + /// Hook, possible types are \p optimistic_queue::base_hook, \p optimistic_queue::member_hook, \p optimistic_queue::traits_hook + typedef optimistic_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 cds::atomicity::empty_item_counter item_counter; + + /// C++ memory ordering model + /** + Can be \p opt::v::relaxed_ordering (relaxed memory model, the default) + or \p opt::v::sequential_consistent (sequentially consisnent memory model). + */ + typedef opt::v::relaxed_ordering memory_model; + + /// Internal statistics (by default, disabled) + /** + Possible option value are: \p optimistic_queue::stat, \p optimistic_queue::empty_stat (the default), + user-provided class that supports \p %optimistic_queue::stat interface. + */ + typedef optimistic_queue::empty_stat stat; + + /// 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 optimistic_queue::traits + /** + Supported \p Options are: + + - opt::hook - hook used. Possible hooks are: \p optimistic_queue::base_hook, \p optimistic_queue::member_hook, \p optimistic_queue::traits_hook. + If the option is not specified, \p %optimistic_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 optimistic_queue::stat, \p optimistic_queue::empty_stat, + user-provided class that supports \p %optimistic_queue::stat interface. + Default is \p %optimistic_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 %OptimisticQueue with item counting and internal statistics + \code + typedef cds::intrusive::OptimisticQueue< cds::gc::HP, Foo, + typename cds::intrusive::optimistic_queue::make_traits< + cds::intrusive::opt:hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc >>, + cds::opt::item_counte< cds::atomicity::item_counter >, + cds::opt::stat< cds::intrusive::optimistic_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 optimistic_queue - /// Optimistic queue + /// Optimistic intruive lock-free queue /** @ingroup cds_intrusive_queue Implementation of Ladan-Mozes & Shavit optimistic queue algorithm. - - \par Source: [2008] Edya Ladan-Mozes, Nir Shavit "An Optimistic Approach to Lock-Free FIFO Queues" Template arguments: - - \p GC - garbage collector type: gc::HP, gc::PTB. Note that gc::HRC is not supported - - \p T - type to be stored in the queue - - \p Options - options - - Type of node: \ref optimistic_queue::node. - - \p Options are: - - opt::hook - hook used. Possible values are: optimistic_queue::base_hook, optimistic_queue::member_hook, optimistic_queue::traits_hook. - If the option is not specified, optimistic_queue::base_hook<> is used. - - 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 - - opt::item_counter - the type of item counting feature. Default is \ref atomicity::empty_item_counter - - opt::stat - the type to gather internal statistics. - Possible option value are: optimistic_queue::stat, optimistic_queue::dummy_stat, - user-provided class that supports optimistic_queue::stat interface. - Generic option intrusive::queue_stat and intrusive::queue_dummy_stat are acceptable too, however, - they will be automatically converted to optimistic_queue::stat and optimistic_queue::dummy_stat - respectively. - Default is \ref optimistic_queue::dummy_stat. - - 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. A value of type \p T must be derived from \p optimistic_queue::node for \p optimistic_queue::base_hook, + or it should have a member of type \p %optimistic_queue::node for \p optimistic_queue::member_hook, + or it should be convertible to \p %optimistic_queue::node for \p optimistic_queue::traits_hook. + - \p Traits - queue traits, default is \p optimistic_queue::traits. You can use \p optimistic_queue::make_traits + metafunction to make your traits or just derive your traits from \p %optimistic_queue::traits: + \code + struct myTraits: public cds::intrusive::optimistic_queue::traits { + typedef cds::intrusive::optimistic_queue::stat<> stat; + typedef cds::atomicity::item_counter item_counter; + }; + typedef cds::intrusive::OptimisticQueue< cds::gc::HP, Foo, myTraits > myQueue; + + // Equivalent make_traits example: + typedef cds::intrusive::OptimisticQueue< cds::gc::HP, Foo, + typename cds::intrusive::optimistic_queue::make_traits< + cds::opt::stat< cds::intrusive::optimistic_queue::stat<> >, + cds::opt::item_counter< cds::atomicity::item_counter > + >::type + > myQueue; + \endcode Garbage collecting schema \p GC must be consistent with the optimistic_queue::node GC. \par About item disposing The optimistic 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 for explanation. + the standpoint of the algo. See \p dequeue() function for explanation. \par Examples \code - #include #include + #include namespace ci = cds::inrtusive; typedef cds::gc::HP hp_gc; @@ -258,11 +357,13 @@ namespace cds { namespace intrusive { }; typedef ci::OptimisticQueue< hp_gc, - Foo - ,ci::opt::hook< - ci::optimistic_queue::base_hook< ci::opt::gc< hp_gc > > - > - ,cds::opt::item_counter< cds::atomicity::item_counter > + Foo, + typename ci::optimistic_queue::make_traits< + ci::opt::hook< + ci::optimistic_queue::base_hook< ci::opt::gc< hp_gc > > + > + ,cds::opt::item_counter< cds::atomicity::item_counter > + >::type > FooQueue; // Optimistic queue with Hazard Pointer garbage collector, member hook, no item counter: @@ -274,103 +375,59 @@ namespace cds { namespace intrusive { }; typedef ci::OptimisticQueue< hp_gc, - Bar - ,ci::opt::hook< - ci::optimistic_queue::member_hook< - offsetof(Bar, hMember) - ,ci::opt::gc< hp_gc > + Bar, + typename ci::optimistic_queue::make_traits< + ci::opt::hook< + ci::optimistic_queue::member_hook< + offsetof(Bar, hMember) + ,ci::opt::gc< hp_gc > + > > - > + >::type > BarQueue; - \endcode */ - template + template class OptimisticQueue { - //@cond - struct default_options - { - typedef cds::backoff::empty back_off; - typedef optimistic_queue::base_hook<> hook; - typedef opt::v::empty_disposer disposer; - typedef atomicity::empty_item_counter item_counter; - typedef opt::v::relaxed_ordering memory_model; - typedef optimistic_queue::dummy_stat stat; - 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 - ,optimistic_queue::stat<> - ,typename std::conditional< - std::is_same::value - ,optimistic_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 optimistic_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 - typedef typename options::memory_model memory_model ; ///< Memory ordering. See cds::opt::memory_model option -#ifdef CDS_DOXYGEN_INVOKED - typedef typename options::stat stat ; ///< Internal statistics policy used -#else - typedef stat_type_ stat; -#endif + typedef GC gc; ///< Garbage collector + typedef T value_type; ///< type of value to be 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 optimistic_queue::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::memory_model memory_model;///< Memory ordering. See cds::opt::memory_model option + typedef typename traits::stat stat; ///< Internal statistics policy used /// Rebind template arguments - template + template struct rebind { - typedef OptimisticQueue< GC2, T2, Options2...> other ; ///< Rebinding result + typedef OptimisticQueue< GC2, T2, Traits2 > other ; ///< Rebinding result }; protected: //@cond + typedef intrusive::node_to_value node_to_value; + typedef typename opt::details::alignment_setter< typename node_type::atomic_node_ptr, traits::alignment >::type aligned_node_ptr; - struct internal_disposer - { - void operator ()( value_type * p ) - { - assert( p != nullptr ); - - OptimisticQueue::clear_links( node_traits::to_node_ptr(*p) ); - disposer()( p ); - } - }; + // GC and node_type::gc must be the same + static_assert((std::is_same::value), "GC and node_type::gc must be the same"); - typedef intrusive::node_to_value node_to_value; - typedef typename opt::details::alignment_setter< typename node_type::atomic_node_ptr, options::alignment >::type aligned_node_ptr; //@endcond aligned_node_ptr m_pTail ; ///< Pointer to tail node aligned_node_ptr m_pHead ; ///< Pointer to head node - node_type m_Dummy ; ///< dummy node - + node_type m_Dummy ; ///< dummy node item_counter m_ItemCounter ; ///< Item counter stat m_Stat ; ///< Internal statistics - static CDS_CONSTEXPR_CONST size_t c_nHazardPtrCount = 5 ; ///< Count of hazard pointer required for the algorithm + static CDS_CONSTEXPR const size_t c_nHazardPtrCount = 5 ; ///< Count of hazard pointer required for the algorithm protected: //@cond @@ -464,6 +521,16 @@ namespace cds { namespace intrusive { assert( p != nullptr ); if ( p != &m_Dummy ) { + struct internal_disposer + { + void operator ()( value_type * p ) + { + assert( p != nullptr ); + + OptimisticQueue::clear_links( node_traits::to_node_ptr( *p ) ); + disposer()(p); + } + }; gc::template retire( node_traits::to_value_ptr(p) ); } } @@ -473,18 +540,9 @@ namespace cds { namespace intrusive { public: /// Constructor creates empty queue OptimisticQueue() - : m_pTail( nullptr ) - , m_pHead( nullptr ) - { - // GC and node_type::gc must be the same - static_assert(( std::is_same::value ), "GC and node_type::gc must be the same"); - - // cds::gc::HRC is not allowed - static_assert(( !std::is_same::value ), "cds::gc::HRC is not allowed here"); - - m_pTail.store( &m_Dummy, memory_model::memory_order_relaxed ); - m_pHead.store( &m_Dummy, memory_model::memory_order_relaxed ); - } + : m_pTail( &m_Dummy ) + , m_pHead( &m_Dummy ) + {} ~OptimisticQueue() { @@ -517,7 +575,7 @@ namespace cds { namespace intrusive { pTail->m_pPrev.store( pNew, memory_model::memory_order_release ) ; // Success, write prev ++m_ItemCounter; m_Stat.onEnqueue(); - break ; // Enqueue done! + break ; // Enqueue done! } guards.assign( 0, node_traits::to_value_ptr( pTail ) ) ; // pTail has been changed by CAS above m_Stat.onEnqueueRace(); @@ -561,19 +619,19 @@ namespace cds { namespace intrusive { return nullptr; } - /// Synonym for @ref cds_intrusive_OptimisticQueue_enqueue "enqueue" + /// Synonym for \p enqueue() bool push( value_type& val ) { return enqueue( val ); } - /// Synonym for \ref cds_intrusive_OptimisticQueue_dequeue "dequeue" + /// Synonym for \p dequeue() value_type * pop() { return dequeue(); } - /// Checks if queue is empty + /// Checks if the queue is empty bool empty() const { return m_pTail.load(memory_model::memory_order_relaxed) == m_pHead.load(memory_model::memory_order_relaxed); @@ -582,7 +640,7 @@ namespace cds { namespace intrusive { /// Clear the stack /** The function repeatedly calls \ref dequeue until it returns \p nullptr. - The disposer defined in template \p Options is called for each item + The disposer defined in template \p Traits is called for each item that can be safely disposed. */ void clear() @@ -593,11 +651,11 @@ namespace cds { namespace intrusive { /// Returns queue's item count /** - The value returned depends on opt::item_counter option. For atomicity::empty_item_counter, - this function always returns 0. + The value returned depends on \p optimistic_queue::traits::item_counter. + For \p 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. + @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 { diff --git a/projects/Win/vc12/hdr-test-queue.vcxproj b/projects/Win/vc12/hdr-test-queue.vcxproj index 2eeb7ee8..0f7646ad 100644 --- a/projects/Win/vc12/hdr-test-queue.vcxproj +++ b/projects/Win/vc12/hdr-test-queue.vcxproj @@ -545,8 +545,8 @@ + - diff --git a/projects/Win/vc12/hdr-test-queue.vcxproj.filters b/projects/Win/vc12/hdr-test-queue.vcxproj.filters index eb90ff49..5b34321c 100644 --- a/projects/Win/vc12/hdr-test-queue.vcxproj.filters +++ b/projects/Win/vc12/hdr-test-queue.vcxproj.filters @@ -19,9 +19,6 @@ intrusive - - intrusive - intrusive @@ -80,6 +77,9 @@ container + + intrusive + diff --git a/projects/source.test-hdr.offsetof.mk b/projects/source.test-hdr.offsetof.mk index 71f363bd..d2da5258 100644 --- a/projects/source.test-hdr.offsetof.mk +++ b/projects/source.test-hdr.offsetof.mk @@ -74,7 +74,7 @@ CDS_TESTHDR_OFFSETOF_QUEUE := \ tests/test-hdr/queue/hdr_intrusive_msqueue_hp.cpp \ tests/test-hdr/queue/hdr_intrusive_msqueue_dhp.cpp \ tests/test-hdr/queue/hdr_intrusive_optimisticqueue_hp.cpp \ - tests/test-hdr/queue/hdr_intrusive_optimisticqueue_ptb.cpp + tests/test-hdr/queue/hdr_intrusive_optimisticqueue_dhp.cpp CDS_TESTHDR_OFFSETOF_STACK := \ tests/test-hdr/stack/hdr_intrusive_treiber_stack_hp.cpp \ diff --git a/tests/test-hdr/queue/hdr_intrusive_msqueue.h b/tests/test-hdr/queue/hdr_intrusive_msqueue.h index 05c6ac46..5c46b777 100644 --- a/tests/test-hdr/queue/hdr_intrusive_msqueue.h +++ b/tests/test-hdr/queue/hdr_intrusive_msqueue.h @@ -339,18 +339,18 @@ namespace queue { void test_OptimisticQueue_HP_member_noalign(); void test_OptimisticQueue_HP_base_cachealign(); void test_OptimisticQueue_HP_member_cachealign(); - void test_OptimisticQueue_PTB_base(); - void test_OptimisticQueue_PTB_member(); - void test_OptimisticQueue_PTB_base_ic(); - void test_OptimisticQueue_PTB_member_ic(); - void test_OptimisticQueue_PTB_base_stat(); - void test_OptimisticQueue_PTB_member_stat(); - void test_OptimisticQueue_PTB_base_align(); - void test_OptimisticQueue_PTB_member_align(); - void test_OptimisticQueue_PTB_base_noalign(); - void test_OptimisticQueue_PTB_member_noalign(); - void test_OptimisticQueue_PTB_base_cachealign(); - void test_OptimisticQueue_PTB_member_cachealign(); + void test_OptimisticQueue_DHP_base(); + void test_OptimisticQueue_DHP_member(); + void test_OptimisticQueue_DHP_base_ic(); + void test_OptimisticQueue_DHP_member_ic(); + void test_OptimisticQueue_DHP_base_stat(); + void test_OptimisticQueue_DHP_member_stat(); + void test_OptimisticQueue_DHP_base_align(); + void test_OptimisticQueue_DHP_member_align(); + void test_OptimisticQueue_DHP_base_noalign(); + void test_OptimisticQueue_DHP_member_noalign(); + void test_OptimisticQueue_DHP_base_cachealign(); + void test_OptimisticQueue_DHP_member_cachealign(); void test_BasketQueue_HP_default(); void test_BasketQueue_HP_default_ic(); @@ -462,18 +462,18 @@ namespace queue { CPPUNIT_TEST(test_OptimisticQueue_HP_member_noalign) CPPUNIT_TEST(test_OptimisticQueue_HP_base_cachealign) CPPUNIT_TEST(test_OptimisticQueue_HP_member_cachealign) - CPPUNIT_TEST(test_OptimisticQueue_PTB_base) - CPPUNIT_TEST(test_OptimisticQueue_PTB_member) - CPPUNIT_TEST(test_OptimisticQueue_PTB_base_ic) - CPPUNIT_TEST(test_OptimisticQueue_PTB_member_ic) - CPPUNIT_TEST(test_OptimisticQueue_PTB_base_stat) - CPPUNIT_TEST(test_OptimisticQueue_PTB_member_stat) - CPPUNIT_TEST(test_OptimisticQueue_PTB_base_align) - CPPUNIT_TEST(test_OptimisticQueue_PTB_member_align) - CPPUNIT_TEST(test_OptimisticQueue_PTB_base_noalign) - CPPUNIT_TEST(test_OptimisticQueue_PTB_member_noalign) - CPPUNIT_TEST(test_OptimisticQueue_PTB_base_cachealign) - CPPUNIT_TEST(test_OptimisticQueue_PTB_member_cachealign) + CPPUNIT_TEST(test_OptimisticQueue_DHP_base) + CPPUNIT_TEST(test_OptimisticQueue_DHP_member) + CPPUNIT_TEST(test_OptimisticQueue_DHP_base_ic) + CPPUNIT_TEST(test_OptimisticQueue_DHP_member_ic) + CPPUNIT_TEST(test_OptimisticQueue_DHP_base_stat) + CPPUNIT_TEST(test_OptimisticQueue_DHP_member_stat) + CPPUNIT_TEST(test_OptimisticQueue_DHP_base_align) + CPPUNIT_TEST(test_OptimisticQueue_DHP_member_align) + CPPUNIT_TEST(test_OptimisticQueue_DHP_base_noalign) + CPPUNIT_TEST(test_OptimisticQueue_DHP_member_noalign) + CPPUNIT_TEST(test_OptimisticQueue_DHP_base_cachealign) + CPPUNIT_TEST(test_OptimisticQueue_DHP_member_cachealign) CPPUNIT_TEST(test_BasketQueue_HP_default) CPPUNIT_TEST(test_BasketQueue_HP_default_ic) diff --git a/tests/test-hdr/queue/hdr_intrusive_optimisticqueue_dhp.cpp b/tests/test-hdr/queue/hdr_intrusive_optimisticqueue_dhp.cpp new file mode 100644 index 00000000..34bf0b86 --- /dev/null +++ b/tests/test-hdr/queue/hdr_intrusive_optimisticqueue_dhp.cpp @@ -0,0 +1,186 @@ +//$$CDS-header$$ + +#include "hdr_intrusive_msqueue.h" +#include +#include + +namespace queue { + +#define TEST(X) void IntrusiveQueueHeaderTest::test_##X() { test(); } + + namespace { + struct base_hook_item: public ci::optimistic_queue::node< cds::gc::DHP > + { + int nVal; + int nDisposeCount; + + base_hook_item() + : nDisposeCount(0) + {} + }; + + struct member_hook_item + { + int nVal; + int nDisposeCount; + ci::optimistic_queue::node< cds::gc::DHP > hMember; + + member_hook_item() + : nDisposeCount(0) + {} + }; + + // DHP base hook + typedef ci::OptimisticQueue< cds::gc::DHP, base_hook_item, + typename ci::optimistic_queue::make_traits< + ci::opt::hook< + ci::optimistic_queue::base_hook< ci::opt::gc > + > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,co::memory_model< co::v::relaxed_ordering > + >::type + > OptimisticQueue_DHP_base; + + // DHP member hook + struct traits_OptimisticQueue_DHP_member : public OptimisticQueue_DHP_base::traits + { + typedef ci::optimistic_queue::member_hook < + offsetof( member_hook_item, hMember ), + ci::opt::gc < cds::gc::DHP > + > hook; + }; + typedef ci::OptimisticQueue< cds::gc::DHP, member_hook_item, traits_OptimisticQueue_DHP_member > OptimisticQueue_DHP_member; + + /// DHP base hook + item counter + typedef ci::OptimisticQueue< cds::gc::DHP, base_hook_item, + typename ci::optimistic_queue::make_traits< + ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,ci::opt::hook< + ci::optimistic_queue::base_hook< ci::opt::gc > + > + ,co::item_counter< cds::atomicity::item_counter > + >::type + > OptimisticQueue_DHP_base_ic; + + // DHP member hook + item counter + typedef ci::OptimisticQueue< cds::gc::DHP, member_hook_item, + typename ci::optimistic_queue::make_traits< + cds::opt::type_traits< traits_OptimisticQueue_DHP_member > + ,co::item_counter< cds::atomicity::item_counter > + >::type + > OptimisticQueue_DHP_member_ic; + + // DHP base hook + stat + typedef ci::OptimisticQueue< cds::gc::DHP, base_hook_item, + typename ci::optimistic_queue::make_traits< + ci::opt::hook< + ci::optimistic_queue::base_hook< ci::opt::gc > + > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,co::stat< ci::optimistic_queue::stat<> > + >::type + > OptimisticQueue_DHP_base_stat; + + // DHP member hook + stat + typedef ci::OptimisticQueue< cds::gc::DHP, member_hook_item, + typename ci::optimistic_queue::make_traits< + cds::opt::type_traits< OptimisticQueue_DHP_base_stat::traits > + , ci::opt::hook< + ci::optimistic_queue::member_hook< + offsetof(member_hook_item, hMember), + ci::opt::gc + > + > + >::type + > OptimisticQueue_DHP_member_stat; + + // DHP base hook + alignment + typedef ci::OptimisticQueue< cds::gc::DHP, base_hook_item, + typename ci::optimistic_queue::make_traits< + ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,ci::opt::hook< + ci::optimistic_queue::base_hook< ci::opt::gc > + > + ,co::alignment< 32 > + >::type + > OptimisticQueue_DHP_base_align; + + // DHP member hook + alignment + typedef ci::OptimisticQueue< cds::gc::DHP, member_hook_item, + typename ci::optimistic_queue::make_traits< + ci::opt::hook< + ci::optimistic_queue::member_hook< + offsetof(member_hook_item, hMember), + ci::opt::gc + > + > + ,co::alignment< 32 > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + >::type + > OptimisticQueue_DHP_member_align; + + // DHP base hook + no alignment + typedef ci::OptimisticQueue< cds::gc::DHP, base_hook_item, + typename ci::optimistic_queue::make_traits< + ci::opt::hook< + ci::optimistic_queue::base_hook< ci::opt::gc > + > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,co::alignment< co::no_special_alignment > + >::type + > OptimisticQueue_DHP_base_noalign; + + // DHP member hook + no alignment + typedef ci::OptimisticQueue< cds::gc::DHP, member_hook_item, + typename ci::optimistic_queue::make_traits< + ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,ci::opt::hook< + ci::optimistic_queue::member_hook< + offsetof(member_hook_item, hMember), + ci::opt::gc + > + > + ,co::alignment< co::no_special_alignment > + >::type + > OptimisticQueue_DHP_member_noalign; + + + // DHP base hook + cache alignment + typedef ci::OptimisticQueue< cds::gc::DHP, base_hook_item, + typename ci::optimistic_queue::make_traits< + ci::opt::hook< + ci::optimistic_queue::base_hook< ci::opt::gc > + > + ,co::alignment< co::cache_line_alignment > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + >::type + > OptimisticQueue_DHP_base_cachealign; + + // DHP member hook + cache alignment + typedef ci::OptimisticQueue< cds::gc::DHP, member_hook_item, + typename ci::optimistic_queue::make_traits< + ci::opt::hook< + ci::optimistic_queue::member_hook< + offsetof(member_hook_item, hMember), + ci::opt::gc + > + > + ,co::alignment< co::cache_line_alignment > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + >::type + > OptimisticQueue_DHP_member_cachealign; + } + + TEST(OptimisticQueue_DHP_base) + TEST(OptimisticQueue_DHP_member) + TEST(OptimisticQueue_DHP_base_ic) + TEST(OptimisticQueue_DHP_member_ic) + TEST(OptimisticQueue_DHP_base_stat) + TEST(OptimisticQueue_DHP_member_stat) + TEST(OptimisticQueue_DHP_base_align) + TEST(OptimisticQueue_DHP_member_align) + TEST(OptimisticQueue_DHP_base_noalign) + TEST(OptimisticQueue_DHP_member_noalign) + TEST(OptimisticQueue_DHP_base_cachealign) + TEST(OptimisticQueue_DHP_member_cachealign) +} diff --git a/tests/test-hdr/queue/hdr_intrusive_optimisticqueue_hp.cpp b/tests/test-hdr/queue/hdr_intrusive_optimisticqueue_hp.cpp index 7cfecbe8..cd5bbc05 100644 --- a/tests/test-hdr/queue/hdr_intrusive_optimisticqueue_hp.cpp +++ b/tests/test-hdr/queue/hdr_intrusive_optimisticqueue_hp.cpp @@ -1,16 +1,15 @@ //$$CDS-header$$ #include "hdr_intrusive_msqueue.h" -#include #include +#include namespace queue { #define TEST(X) void IntrusiveQueueHeaderTest::test_##X() { test(); } namespace { - template - struct base_hook_item: public ci::optimistic_queue::node< GC > + struct base_hook_item: public ci::optimistic_queue::node< cds::gc::HP > { int nVal; int nDisposeCount; @@ -20,177 +19,179 @@ namespace queue { {} }; - template struct member_hook_item { - ci::optimistic_queue::node< GC > hMember; int nVal; int nDisposeCount; + ci::optimistic_queue::node< cds::gc::HP > hMember; member_hook_item() : nDisposeCount(0) {} }; - - typedef ci::OptimisticQueue< cds::gc::HP, - base_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - > OptimisticQueue_HP_default; + struct traits_OptimisticQueue_HP_default : public ci::optimistic_queue::traits + { + typedef IntrusiveQueueHeaderTest::faked_disposer disposer; + }; + typedef ci::OptimisticQueue< cds::gc::HP, base_hook_item, traits_OptimisticQueue_HP_default > OptimisticQueue_HP_default; /// HP + item counter - typedef ci::OptimisticQueue< cds::gc::HP, - base_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::item_counter< cds::atomicity::item_counter > - > OptimisticQueue_HP_default_ic; + struct traits_OptimisticQueue_HP_default_ic : public traits_OptimisticQueue_HP_default + { + typedef cds::atomicity::item_counter item_counter; + }; + typedef ci::OptimisticQueue< cds::gc::HP, base_hook_item, traits_OptimisticQueue_HP_default_ic > OptimisticQueue_HP_default_ic; /// HP + stat - typedef ci::OptimisticQueue< cds::gc::HP, - base_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::stat< ci::queue_stat<> > - ,co::memory_model< co::v::sequential_consistent > - > OptimisticQueue_HP_default_stat; + struct traits_OptimisticQueue_HP_default_stat : public + ci::optimistic_queue::make_traits < + ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + , co::stat< ci::optimistic_queue::stat<> > + , co::memory_model< co::v::sequential_consistent > + > ::type + {}; + typedef ci::OptimisticQueue< cds::gc::HP, base_hook_item, traits_OptimisticQueue_HP_default_stat > OptimisticQueue_HP_default_stat; // HP base hook - typedef ci::OptimisticQueue< cds::gc::HP, - base_hook_item - ,ci::opt::hook< - ci::optimistic_queue::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::memory_model< co::v::relaxed_ordering > + typedef ci::OptimisticQueue< cds::gc::HP, base_hook_item, + typename ci::optimistic_queue::make_traits< + ci::opt::hook< + ci::optimistic_queue::base_hook< ci::opt::gc > + > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,co::memory_model< co::v::relaxed_ordering > + >::type > OptimisticQueue_HP_base; // HP member hook - typedef ci::OptimisticQueue< cds::gc::HP, - member_hook_item - ,ci::opt::hook< - ci::optimistic_queue::member_hook< - offsetof(member_hook_item, hMember), - ci::opt::gc - > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - > OptimisticQueue_HP_member; + struct traits_OptimisticQueue_HP_member : public OptimisticQueue_HP_base::traits + { + typedef ci::optimistic_queue::member_hook < + offsetof( member_hook_item, hMember ), + ci::opt::gc < cds::gc::HP > + > hook; + }; + typedef ci::OptimisticQueue< cds::gc::HP, member_hook_item, traits_OptimisticQueue_HP_member > OptimisticQueue_HP_member; /// HP base hook + item counter - typedef ci::OptimisticQueue< cds::gc::HP, - base_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::optimistic_queue::base_hook< ci::opt::gc > - > - ,co::item_counter< cds::atomicity::item_counter > + typedef ci::OptimisticQueue< cds::gc::HP, base_hook_item, + typename ci::optimistic_queue::make_traits< + ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,ci::opt::hook< + ci::optimistic_queue::base_hook< ci::opt::gc > + > + ,co::item_counter< cds::atomicity::item_counter > + >::type > OptimisticQueue_HP_base_ic; // HP member hook + item counter - typedef ci::OptimisticQueue< cds::gc::HP, - member_hook_item - ,ci::opt::hook< - ci::optimistic_queue::member_hook< - offsetof(member_hook_item, hMember), - ci::opt::gc - > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::item_counter< cds::atomicity::item_counter > + typedef ci::OptimisticQueue< cds::gc::HP, member_hook_item, + typename ci::optimistic_queue::make_traits< + cds::opt::type_traits< traits_OptimisticQueue_HP_member > + ,co::item_counter< cds::atomicity::item_counter > + >::type > OptimisticQueue_HP_member_ic; // HP base hook + stat - typedef ci::OptimisticQueue< cds::gc::HP, - base_hook_item - ,ci::opt::hook< - ci::optimistic_queue::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::stat< ci::queue_stat<> > + typedef ci::OptimisticQueue< cds::gc::HP, base_hook_item, + typename ci::optimistic_queue::make_traits< + ci::opt::hook< + ci::optimistic_queue::base_hook< ci::opt::gc > + > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,co::stat< ci::optimistic_queue::stat<> > + >::type > OptimisticQueue_HP_base_stat; // HP member hook + stat - typedef ci::OptimisticQueue< cds::gc::HP, - member_hook_item - ,ci::opt::hook< - ci::optimistic_queue::member_hook< - offsetof(member_hook_item, hMember), - ci::opt::gc + typedef ci::OptimisticQueue< cds::gc::HP, member_hook_item, + typename ci::optimistic_queue::make_traits< + cds::opt::type_traits< OptimisticQueue_HP_base_stat::traits > + , ci::opt::hook< + ci::optimistic_queue::member_hook< + offsetof(member_hook_item, hMember), + ci::opt::gc + > > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::stat< ci::queue_stat<> > + >::type > OptimisticQueue_HP_member_stat; // HP base hook + alignment - typedef ci::OptimisticQueue< cds::gc::HP, - base_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::optimistic_queue::base_hook< ci::opt::gc > - > - ,co::alignment< 32 > + typedef ci::OptimisticQueue< cds::gc::HP, base_hook_item, + typename ci::optimistic_queue::make_traits< + ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,ci::opt::hook< + ci::optimistic_queue::base_hook< ci::opt::gc > + > + ,co::alignment< 32 > + >::type > OptimisticQueue_HP_base_align; // HP member hook + alignment - typedef ci::OptimisticQueue< cds::gc::HP, - member_hook_item - ,ci::opt::hook< - ci::optimistic_queue::member_hook< - offsetof(member_hook_item, hMember), - ci::opt::gc + typedef ci::OptimisticQueue< cds::gc::HP, member_hook_item, + typename ci::optimistic_queue::make_traits< + ci::opt::hook< + ci::optimistic_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 > OptimisticQueue_HP_member_align; // HP base hook + no alignment - typedef ci::OptimisticQueue< cds::gc::HP, - base_hook_item - ,ci::opt::hook< - ci::optimistic_queue::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::alignment< co::no_special_alignment > + typedef ci::OptimisticQueue< cds::gc::HP, base_hook_item, + typename ci::optimistic_queue::make_traits< + ci::opt::hook< + ci::optimistic_queue::base_hook< ci::opt::gc > + > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,co::alignment< co::no_special_alignment > + >::type > OptimisticQueue_HP_base_noalign; // HP member hook + no alignment - typedef ci::OptimisticQueue< cds::gc::HP, - member_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::optimistic_queue::member_hook< - offsetof(member_hook_item, hMember), - ci::opt::gc + typedef ci::OptimisticQueue< cds::gc::HP, member_hook_item, + typename ci::optimistic_queue::make_traits< + ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + ,ci::opt::hook< + ci::optimistic_queue::member_hook< + offsetof(member_hook_item, hMember), + ci::opt::gc + > > - > - ,co::alignment< co::no_special_alignment > + ,co::alignment< co::no_special_alignment > + >::type > OptimisticQueue_HP_member_noalign; // HP base hook + cache alignment - typedef ci::OptimisticQueue< cds::gc::HP, - base_hook_item - ,ci::opt::hook< - ci::optimistic_queue::base_hook< ci::opt::gc > - > - ,co::alignment< co::cache_line_alignment > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + typedef ci::OptimisticQueue< cds::gc::HP, base_hook_item, + typename ci::optimistic_queue::make_traits< + ci::opt::hook< + ci::optimistic_queue::base_hook< ci::opt::gc > + > + ,co::alignment< co::cache_line_alignment > + ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > + >::type > OptimisticQueue_HP_base_cachealign; // HP member hook + cache alignment - typedef ci::OptimisticQueue< cds::gc::HP, - member_hook_item - ,ci::opt::hook< - ci::optimistic_queue::member_hook< - offsetof(member_hook_item, hMember), - ci::opt::gc + typedef ci::OptimisticQueue< cds::gc::HP, member_hook_item, + typename ci::optimistic_queue::make_traits< + ci::opt::hook< + ci::optimistic_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 > OptimisticQueue_HP_member_cachealign; - } TEST(OptimisticQueue_HP_default) diff --git a/tests/test-hdr/queue/hdr_intrusive_optimisticqueue_ptb.cpp b/tests/test-hdr/queue/hdr_intrusive_optimisticqueue_ptb.cpp deleted file mode 100644 index 71261cfc..00000000 --- a/tests/test-hdr/queue/hdr_intrusive_optimisticqueue_ptb.cpp +++ /dev/null @@ -1,187 +0,0 @@ -//$$CDS-header$$ - -#include "hdr_intrusive_msqueue.h" -#include -#include - -namespace queue { - -#define TEST(X) void IntrusiveQueueHeaderTest::test_##X() { test(); } - - namespace { - template - struct base_hook_item: public ci::optimistic_queue::node< GC > - { - int nVal; - int nDisposeCount; - - base_hook_item() - : nDisposeCount(0) - {} - }; - - template - struct member_hook_item - { - int nVal; - int nDisposeCount; - ci::optimistic_queue::node< GC > hMember; - - member_hook_item() - : nDisposeCount(0) - {} - }; - - // PTB base hook - typedef ci::OptimisticQueue< cds::gc::PTB, - base_hook_item - ,ci::opt::hook< - ci::optimistic_queue::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - > OptimisticQueue_PTB_base; - - // PTB member hook - typedef ci::OptimisticQueue< cds::gc::PTB, - member_hook_item - ,ci::opt::hook< - ci::optimistic_queue::member_hook< - offsetof(member_hook_item, hMember), - ci::opt::gc - > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - > OptimisticQueue_PTB_member; - - /// PTB base hook + item counter - typedef ci::OptimisticQueue< cds::gc::PTB, - base_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::optimistic_queue::base_hook< ci::opt::gc > - > - ,co::item_counter< cds::atomicity::item_counter > - > OptimisticQueue_PTB_base_ic; - - // PTB member hook + item counter - typedef ci::OptimisticQueue< cds::gc::PTB, - member_hook_item - ,ci::opt::hook< - ci::optimistic_queue::member_hook< - offsetof(member_hook_item, hMember), - ci::opt::gc - > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::item_counter< cds::atomicity::item_counter > - > OptimisticQueue_PTB_member_ic; - - // PTB base hook + stat - typedef ci::OptimisticQueue< cds::gc::PTB, - base_hook_item - ,ci::opt::hook< - ci::optimistic_queue::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::stat< ci::queue_stat<> > - > OptimisticQueue_PTB_base_stat; - - // PTB member hook + stat - typedef ci::OptimisticQueue< cds::gc::PTB, - member_hook_item - ,ci::opt::hook< - ci::optimistic_queue::member_hook< - offsetof(member_hook_item, hMember), - ci::opt::gc - > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::stat< ci::queue_stat<> > - > OptimisticQueue_PTB_member_stat; - - // PTB base hook + alignment - typedef ci::OptimisticQueue< cds::gc::PTB, - base_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::optimistic_queue::base_hook< ci::opt::gc > - > - ,co::alignment< 32 > - > OptimisticQueue_PTB_base_align; - - // PTB member hook + alignment - typedef ci::OptimisticQueue< cds::gc::PTB, - member_hook_item - ,ci::opt::hook< - ci::optimistic_queue::member_hook< - offsetof(member_hook_item, hMember), - ci::opt::gc - > - > - ,co::alignment< 32 > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - > OptimisticQueue_PTB_member_align; - - // PTB base hook + no alignment - typedef ci::OptimisticQueue< cds::gc::PTB, - base_hook_item - ,ci::opt::hook< - ci::optimistic_queue::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,co::alignment< co::no_special_alignment > - > OptimisticQueue_PTB_base_noalign; - - // PTB member hook + no alignment - typedef ci::OptimisticQueue< cds::gc::PTB, - member_hook_item - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::optimistic_queue::member_hook< - offsetof(member_hook_item, hMember), - ci::opt::gc - > - > - ,co::alignment< co::no_special_alignment > - > OptimisticQueue_PTB_member_noalign; - - - // PTB base hook + cache alignment - typedef ci::OptimisticQueue< cds::gc::PTB, - base_hook_item - ,ci::opt::hook< - ci::optimistic_queue::base_hook< ci::opt::gc > - > - ,co::alignment< co::cache_line_alignment > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - > OptimisticQueue_PTB_base_cachealign; - - // PTB member hook + cache alignment - typedef ci::OptimisticQueue< cds::gc::PTB, - member_hook_item - ,ci::opt::hook< - ci::optimistic_queue::member_hook< - offsetof(member_hook_item, hMember), - ci::opt::gc - > - > - ,co::alignment< co::cache_line_alignment > - ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > - > OptimisticQueue_PTB_member_cachealign; - - } // namespace - - TEST(OptimisticQueue_PTB_base) - TEST(OptimisticQueue_PTB_member) - TEST(OptimisticQueue_PTB_base_ic) - TEST(OptimisticQueue_PTB_member_ic) - TEST(OptimisticQueue_PTB_base_stat) - TEST(OptimisticQueue_PTB_member_stat) - TEST(OptimisticQueue_PTB_base_align) - TEST(OptimisticQueue_PTB_member_align) - TEST(OptimisticQueue_PTB_base_noalign) - TEST(OptimisticQueue_PTB_member_noalign) - TEST(OptimisticQueue_PTB_base_cachealign) - TEST(OptimisticQueue_PTB_member_cachealign) - -} // namespace queue diff --git a/tests/unit/queue/intrusive_queue_defs.h b/tests/unit/queue/intrusive_queue_defs.h index 03b96c32..43444fee 100644 --- a/tests/unit/queue/intrusive_queue_defs.h +++ b/tests/unit/queue/intrusive_queue_defs.h @@ -52,20 +52,20 @@ TEST_CASE(OptimisticQueue_HP_ic, cds::intrusive::optimistic_queue::node< cds::gc::HP > ) \ TEST_CASE(OptimisticQueue_HP_stat, cds::intrusive::optimistic_queue::node< cds::gc::HP > ) \ TEST_CASE(OptimisticQueue_HP_seqcst, cds::intrusive::optimistic_queue::node< cds::gc::HP > ) \ - TEST_CASE(OptimisticQueue_PTB, cds::intrusive::optimistic_queue::node< cds::gc::PTB > ) \ - TEST_CASE(OptimisticQueue_PTB_ic, cds::intrusive::optimistic_queue::node< cds::gc::PTB > ) \ - TEST_CASE(OptimisticQueue_PTB_stat, cds::intrusive::optimistic_queue::node< cds::gc::PTB > ) \ - TEST_CASE(OptimisticQueue_PTB_seqcst, cds::intrusive::optimistic_queue::node< cds::gc::PTB > ) + TEST_CASE(OptimisticQueue_DHP, cds::intrusive::optimistic_queue::node< cds::gc::DHP > ) \ + TEST_CASE(OptimisticQueue_DHP_ic, cds::intrusive::optimistic_queue::node< cds::gc::DHP > ) \ + TEST_CASE(OptimisticQueue_DHP_stat, cds::intrusive::optimistic_queue::node< cds::gc::DHP > ) \ + TEST_CASE(OptimisticQueue_DHP_seqcst, cds::intrusive::optimistic_queue::node< cds::gc::DHP > ) #define CDSUNIT_TEST_OptimisticQueue \ CPPUNIT_TEST(OptimisticQueue_HP) \ CPPUNIT_TEST(OptimisticQueue_HP_ic) \ CPPUNIT_TEST(OptimisticQueue_HP_stat) \ CPPUNIT_TEST(OptimisticQueue_HP_seqcst) \ - CPPUNIT_TEST(OptimisticQueue_PTB) \ - CPPUNIT_TEST(OptimisticQueue_PTB_ic) \ - CPPUNIT_TEST(OptimisticQueue_PTB_stat) \ - CPPUNIT_TEST(OptimisticQueue_PTB_seqcst) + CPPUNIT_TEST(OptimisticQueue_DHP) \ + CPPUNIT_TEST(OptimisticQueue_DHP_ic) \ + CPPUNIT_TEST(OptimisticQueue_DHP_stat) \ + CPPUNIT_TEST(OptimisticQueue_DHP_seqcst) // BasketQueue diff --git a/tests/unit/queue/intrusive_queue_type.h b/tests/unit/queue/intrusive_queue_type.h index c4ff9ca2..9a0e99b5 100644 --- a/tests/unit/queue/intrusive_queue_type.h +++ b/tests/unit/queue/intrusive_queue_type.h @@ -153,46 +153,67 @@ namespace queue { // OptimisticQueue - typedef cds::intrusive::OptimisticQueue< cds::gc::HP, T - ,cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::HP > > > - > OptimisticQueue_HP; - - typedef cds::intrusive::OptimisticQueue< cds::gc::HP, T - ,cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::HP > > > - ,cds::opt::memory_model< cds::opt::v::sequential_consistent > - > OptimisticQueue_HP_seqcst; + struct traits_OptimisticQueue_HP : public cds::intrusive::optimistic_queue::traits + { + typedef cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::HP > > hook; + }; + typedef cds::intrusive::OptimisticQueue< cds::gc::HP, T, traits_OptimisticQueue_HP > OptimisticQueue_HP; - typedef cds::intrusive::OptimisticQueue< cds::gc::PTB, T - ,cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::PTB > > > - > OptimisticQueue_PTB; + struct traits_OptimisticQueue_HP_seqcst : public + cds::intrusive::optimistic_queue::make_traits < + cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::HP > > > + , cds::opt::memory_model< cds::opt::v::sequential_consistent > + >::type + {}; + typedef cds::intrusive::OptimisticQueue< cds::gc::HP, T, traits_OptimisticQueue_HP_seqcst > OptimisticQueue_HP_seqcst; - typedef cds::intrusive::OptimisticQueue< cds::gc::PTB, T - ,cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::PTB > > > - ,cds::opt::memory_model< cds::opt::v::sequential_consistent > - > OptimisticQueue_PTB_seqcst; + struct traits_OptimisticQueue_DHP : public cds::intrusive::optimistic_queue::traits + { + typedef cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::DHP > > hook; + }; + typedef cds::intrusive::OptimisticQueue< cds::gc::DHP, T, traits_OptimisticQueue_DHP > OptimisticQueue_DHP; + struct traits_OptimisticQueue_DHP_seqcst: public + cds::intrusive::optimistic_queue::make_traits < + cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::DHP > > > + , cds::opt::memory_model< cds::opt::v::sequential_consistent > + >::type + {}; + typedef cds::intrusive::OptimisticQueue< cds::gc::DHP, T, traits_OptimisticQueue_DHP_seqcst > OptimisticQueue_DHP_seqcst; // OptimisticQueue + item counter - typedef cds::intrusive::OptimisticQueue< cds::gc::HP, T - ,cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::HP > > > - ,cds::opt::item_counter< cds::atomicity::item_counter > - > OptimisticQueue_HP_ic; + struct traits_OptimisticQueue_HP_ic: public + cds::intrusive::optimistic_queue::make_traits < + cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::HP > > > + , cds::opt::item_counter< cds::atomicity::item_counter > + >::type + {}; + typedef cds::intrusive::OptimisticQueue< cds::gc::HP, T, traits_OptimisticQueue_HP_ic > OptimisticQueue_HP_ic; - typedef cds::intrusive::OptimisticQueue< cds::gc::PTB, T - ,cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::PTB > > > - ,cds::opt::item_counter< cds::atomicity::item_counter > - > OptimisticQueue_PTB_ic; + struct traits_OptimisticQueue_DHP_ic: public + cds::intrusive::optimistic_queue::make_traits < + cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::DHP > > > + , cds::opt::item_counter< cds::atomicity::item_counter > + >::type + {}; + typedef cds::intrusive::OptimisticQueue< cds::gc::DHP, T, traits_OptimisticQueue_DHP_ic > OptimisticQueue_DHP_ic; // OptimisticQueue + stat - typedef cds::intrusive::OptimisticQueue< cds::gc::HP, T - ,cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::HP > > > - ,cds::opt::stat< cds::intrusive::queue_stat<> > - > OptimisticQueue_HP_stat; - - typedef cds::intrusive::OptimisticQueue< cds::gc::PTB, T - ,cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::PTB > > > - ,cds::opt::stat< cds::intrusive::queue_stat<> > - > OptimisticQueue_PTB_stat; + struct traits_OptimisticQueue_HP_stat: public + cds::intrusive::optimistic_queue::make_traits < + cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::HP > > > + , cds::opt::stat< cds::intrusive::optimistic_queue::stat<> > + >::type + {}; + typedef cds::intrusive::OptimisticQueue< cds::gc::HP, T, traits_OptimisticQueue_HP_stat > OptimisticQueue_HP_stat; + + struct traits_OptimisticQueue_DHP_stat: public + cds::intrusive::optimistic_queue::make_traits < + cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::DHP > > > + , cds::opt::stat< cds::intrusive::optimistic_queue::stat<> > + >::type + {}; + typedef cds::intrusive::OptimisticQueue< cds::gc::DHP, T, traits_OptimisticQueue_DHP_stat > OptimisticQueue_DHP_stat; // TsigasCycleQueue class TsigasCycleQueue_dyn -- 2.34.1