+ /// MSQueue related definitions
+ /** @ingroup cds_intrusive_helper
+ */
+ namespace msqueue {
+
+ /// Queue node
+ /**
+ Template parameters:
+ - GC - garbage collector used
+ - Tag - a \ref cds_intrusive_hook_tag "tag"
+ */
+ template <class GC, typename Tag = opt::none >
+ using node = cds::intrusive::single_link::node< GC, Tag > ;
+
+ /// Base hook
+ /**
+ \p Options are:
+ - opt::gc - garbage collector used.
+ - opt::tag - a \ref cds_intrusive_hook_tag "tag"
+ */
+ template < typename... Options >
+ using base_hook = cds::intrusive::single_link::base_hook< Options...>;
+
+ /// Member hook
+ /**
+ \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 - a \ref cds_intrusive_hook_tag "tag"
+ */
+ template < size_t MemberOffset, typename... Options >
+ using member_hook = cds::intrusive::single_link::member_hook< MemberOffset, Options... >;
+
+ /// Traits hook
+ /**
+ \p NodeTraits defines type traits for node.
+ See \ref node_traits for \p NodeTraits interface description
+
+ \p Options are:
+ - opt::gc - garbage collector used.
+ - opt::tag - a \ref cds_intrusive_hook_tag "tag"
+ */
+ template <typename NodeTraits, typename... Options >
+ using traits_hook = cds::intrusive::single_link::traits_hook< NodeTraits, Options... >;
+
+ /// Queue internal statistics. May be used for debugging or profiling
+ /**
+ 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 <typename Counter = cds::atomicity::event_counter >
+ struct stat
+ {
+ 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"
+
+ /// 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; }
+
+ //@cond
+ void reset()
+ {
+ m_EnqueueCount.reset();
+ m_DequeueCount.reset();
+ m_EnqueueRace.reset();
+ m_DequeueRace.reset();
+ m_AdvanceTailError.reset();
+ m_BadTail.reset();
+ }
+
+ stat& operator +=( stat const& 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();
+
+ return *this;
+ }
+ //@endcond
+ };
+
+ /// Dummy queue statistics - no counting is performed, no overhead. Support interface like \p msqueue::stat
+ struct empty_stat
+ {
+ //@cond
+ void onEnqueue() {}
+ void onDequeue() {}
+ void onEnqueueRace() {}
+ void onDequeueRace() {}
+ void onAdvanceTailFailed() {}
+ void onBadTail() {}
+
+ void reset() {}
+ empty_stat& operator +=( empty_stat const& s )
+ {
+ return *this;
+ }
+ //@endcond
+ };
+
+ /// MSQueue default type traits
+ struct traits
+ {
+ /// Back-off strategy
+ typedef cds::backoff::empty back_off;
+
+ /// Hook, possible types are \p msqueue::base_hook, \p msqueue::member_hook, \p msqueue::traits_hook
+ typedef msqueue::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 msqueue::stat, \p msqueue::empty_stat (the default),
+ user-provided class that supports \p %msqueue::stat interface.
+ */
+ typedef msqueue::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 msqueue::traits
+ /**
+ Supported \p Options are:
+
+ - opt::hook - hook used. Possible hooks are: \p msqueue::base_hook, \p msqueue::member_hook, \p msqueue::traits_hook.
+ If the option is not specified, \p %msqueue::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 msqueue::stat, \p msqueue::empty_stat, user-provided class that supports \p %msqueue::stat interface.
+ 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).
+
+ Example: declare \p %MSQueue with item counting and internal statistics
+ \code
+ typedef cds::intrusive::MSQueue< cds::gc::HP, Foo,
+ typename cds::intrusive::msqueue::make_traits<
+ cds::intrusive::opt:hook< cds::intrusive::msqueue::base_hook< cds::opt::gc<cds:gc::HP> >>,
+ cds::opt::item_counte< cds::atomicity::item_counter >,
+ cds::opt::stat< cds::intrusive::msqueue::stat<> >
+ >::type
+ > myQueue;
+ \endcode
+ */
+ template <typename... Options>
+ struct make_traits {
+# ifdef CDS_DOXYGEN_INVOKED
+ typedef implementation_defined type; ///< Metafunction result
+# else
+ typedef typename cds::opt::make_options<
+ typename cds::opt::find_type_traits< traits, Options... >::type
+ , Options...
+ >::type type;
+# endif
+ };
+ } // namespace msqueue