X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=cds%2Fintrusive%2Fmsqueue.h;h=0683754d603f377c8f16d1da8408e71985cbf71e;hb=f18a70bbede4d78533b0d43c2d89b1a2f470887c;hp=9a81f3a09c71baa85dd70b53d4b4ee16e1970f2b;hpb=18e59aed6abaa4e8d9f1c88f3545c6f963a30c51;p=libcds.git diff --git a/cds/intrusive/msqueue.h b/cds/intrusive/msqueue.h index 9a81f3a0..0683754d 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 @@ -165,15 +163,14 @@ namespace cds { namespace intrusive { typedef opt::v::relaxed_ordering memory_model; /// Link checking, see \p cds::opt::link_checker - static const opt::link_check_type link_checker = opt::debug_check_link; + 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 }; }; /// 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. @@ -186,7 +183,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). @@ -213,8 +210,6 @@ namespace cds { namespace intrusive { >::type type; # endif }; - - } // namespace msqueue /// Michael & Scott's intrusive lock-free queue @@ -224,7 +219,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 @@ -316,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 @@ -336,6 +331,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 @@ -418,15 +415,18 @@ namespace cds { namespace intrusive { // HP retiring cycle since m_Dummy is member of MSQueue and may be destroyed // before HP retiring cycle invocation. // So, we will never clear m_Dummy - if ( p != &m_Dummy ) { - gc::retire( node_traits::to_value_ptr(p), - []( value_type * ptr ) { - assert( ptr != nullptr ); - MSQueue::clear_links( node_traits::to_node_ptr( ptr ) ); - disposer()(ptr); - } - ); - } + + struct disposer_thunk { + void operator()( value_type * p ) const + { + assert( p != nullptr ); + MSQueue::clear_links( node_traits::to_node_ptr( p ) ); + disposer()(p); + } + }; + + if ( p != &m_Dummy ) + gc::template retire( node_traits::to_value_ptr( p ) ); } //@endcond @@ -580,7 +580,6 @@ namespace cds { namespace intrusive { { return m_Stat; } - }; }} // namespace cds::intrusive