/// Metafunction converting option list to \p msqueue::traits
/**
- This is a wrapper for <tt> cds::opt::make_options< type_traits, Options...> </tt>
Supported \p Options are:
- opt::hook - hook used. Possible hooks are: \p msqueue::base_hook, \p msqueue::member_hook, \p msqueue::traits_hook.
>::type type;
# endif
};
-
-
} // namespace msqueue
/// Michael & Scott's intrusive lock-free queue
{
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
#define __CDS_INTRUSIVE_OPTIMISTIC_QUEUE_H
#include <type_traits>
-#include <functional> // ref
#include <cds/intrusive/details/base.h>
#include <cds/cxx11_atomic.h>
#include <cds/gc/default_gc.h>
-#include <cds/gc/hrc/gc_fwd.h>
-#include <cds/intrusive/details/queue_stat.h>
namespace cds { namespace intrusive {
- /// Optimistic queue related definitions
+ /// OptimisticQueue related definitions
/** @ingroup cds_intrusive_helper
*/
namespace optimistic_queue {
/**
\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... >
/// 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... >
\p Options are:
- opt::gc - garbage collector used.
- - opt::tag - tag
+ - opt::tag - a \ref cds_intrusive_hook_tag "tag"
*/
template <typename NodeTraits, typename... Options >
struct traits_hook: public hook< opt::traits_hook_tag, Options... >
/// 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 <typename Counter = cds::atomicity::event_counter >
- 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_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;
}
};
/// 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:gc::HP> >>,
+ cds::opt::item_counte< cds::atomicity::item_counter >,
+ cds::opt::stat< cds::intrusive::optimistic_queue::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 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 <b>not</b> 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, <tt>optimistic_queue::base_hook<></tt> 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 <cds/intrusive/optimistic_queue.h>
#include <cds/gc/hp.h>
+ #include <cds/intrusive/optimistic_queue.h>
namespace ci = cds::inrtusive;
typedef cds::gc::HP hp_gc;
};
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:
};
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 <typename GC, typename T, typename... Options>
+ template <typename GC, typename T, typename Traits = optimistic_queue::traits >
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<typename options::stat, cds::intrusive::queue_stat<> >::value
- ,optimistic_queue::stat<>
- ,typename std::conditional<
- std::is_same<typename options::stat, cds::intrusive::queue_dummy_stat>::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 <typename GC2, typename T2, typename... Options2>
+ template <typename GC2, typename T2, typename Traits2>
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<OptimisticQueue> 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<gc, typename node_type::gc>::value), "GC and node_type::gc must be the same");
- typedef intrusive::node_to_value<OptimisticQueue> 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
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<internal_disposer>( node_traits::to_value_ptr(p) );
}
}
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<gc, typename node_type::gc>::value ), "GC and node_type::gc must be the same");
-
- // cds::gc::HRC is not allowed
- static_assert(( !std::is_same<gc, cds::gc::HRC>::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()
{
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();
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);
/// 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()
/// 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.
- <b>Warning</b>: 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
{
<ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_moirqueue_hp.cpp" />\r
<ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_msqueue_dhp.cpp" />\r
<ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_msqueue_hp.cpp" />\r
+ <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_optimisticqueue_dhp.cpp" />\r
<ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_optimisticqueue_hp.cpp" />\r
- <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_optimisticqueue_ptb.cpp" />\r
<ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_segmented_queue_hp.cpp" />\r
<ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_segmented_queue_ptb.cpp" />\r
<ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_tsigas_cycle_queue.cpp" />\r
<ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_optimisticqueue_hp.cpp">\r
<Filter>intrusive</Filter>\r
</ClCompile>\r
- <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_optimisticqueue_ptb.cpp">\r
- <Filter>intrusive</Filter>\r
- </ClCompile>\r
<ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_segmented_queue_hp.cpp">\r
<Filter>intrusive</Filter>\r
</ClCompile>\r
<ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_basketqueue_hp.cpp">\r
<Filter>container</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_optimisticqueue_dhp.cpp">\r
+ <Filter>intrusive</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<ClInclude Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_msqueue.h">\r
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 \
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();
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)
--- /dev/null
+//$$CDS-header$$
+
+#include "hdr_intrusive_msqueue.h"
+#include <cds/gc/dhp.h>
+#include <cds/intrusive/optimistic_queue.h>
+
+namespace queue {
+
+#define TEST(X) void IntrusiveQueueHeaderTest::test_##X() { test<X>(); }
+
+ 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<cds::gc::DHP> >
+ >
+ ,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<cds::gc::DHP> >
+ >
+ ,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<cds::gc::DHP> >
+ >
+ ,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<cds::gc::DHP>
+ >
+ >
+ >::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<cds::gc::DHP> >
+ >
+ ,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<cds::gc::DHP>
+ >
+ >
+ ,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<cds::gc::DHP> >
+ >
+ ,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<cds::gc::DHP>
+ >
+ >
+ ,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<cds::gc::DHP> >
+ >
+ ,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<cds::gc::DHP>
+ >
+ >
+ ,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)
+}
//$$CDS-header$$
#include "hdr_intrusive_msqueue.h"
-#include <cds/intrusive/optimistic_queue.h>
#include <cds/gc/hp.h>
+#include <cds/intrusive/optimistic_queue.h>
namespace queue {
#define TEST(X) void IntrusiveQueueHeaderTest::test_##X() { test<X>(); }
namespace {
- template <typename GC>
- 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;
{}
};
- template <typename GC>
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<cds::gc::HP>
- ,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<cds::gc::HP>
- ,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<cds::gc::HP>
- ,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<cds::gc::HP>
- ,ci::opt::hook<
- ci::optimistic_queue::base_hook< ci::opt::gc<cds::gc::HP> >
- >
- ,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<cds::gc::HP> >
+ >
+ ,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<cds::gc::HP>
- ,ci::opt::hook<
- ci::optimistic_queue::member_hook<
- offsetof(member_hook_item<cds::gc::HP>, hMember),
- ci::opt::gc<cds::gc::HP>
- >
- >
- ,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<cds::gc::HP>
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,ci::opt::hook<
- ci::optimistic_queue::base_hook< ci::opt::gc<cds::gc::HP> >
- >
- ,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<cds::gc::HP> >
+ >
+ ,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<cds::gc::HP>
- ,ci::opt::hook<
- ci::optimistic_queue::member_hook<
- offsetof(member_hook_item<cds::gc::HP>, hMember),
- ci::opt::gc<cds::gc::HP>
- >
- >
- ,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<cds::gc::HP>
- ,ci::opt::hook<
- ci::optimistic_queue::base_hook< ci::opt::gc<cds::gc::HP> >
- >
- ,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<cds::gc::HP> >
+ >
+ ,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<cds::gc::HP>
- ,ci::opt::hook<
- ci::optimistic_queue::member_hook<
- offsetof(member_hook_item<cds::gc::HP>, hMember),
- ci::opt::gc<cds::gc::HP>
+ 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<cds::gc::HP>
+ >
>
- >
- ,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<cds::gc::HP>
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,ci::opt::hook<
- ci::optimistic_queue::base_hook< ci::opt::gc<cds::gc::HP> >
- >
- ,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<cds::gc::HP> >
+ >
+ ,co::alignment< 32 >
+ >::type
> OptimisticQueue_HP_base_align;
// HP member hook + alignment
- typedef ci::OptimisticQueue< cds::gc::HP,
- member_hook_item<cds::gc::HP>
- ,ci::opt::hook<
- ci::optimistic_queue::member_hook<
- offsetof(member_hook_item<cds::gc::HP>, hMember),
- ci::opt::gc<cds::gc::HP>
+ 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<cds::gc::HP>
+ >
>
- >
- ,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<cds::gc::HP>
- ,ci::opt::hook<
- ci::optimistic_queue::base_hook< ci::opt::gc<cds::gc::HP> >
- >
- ,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<cds::gc::HP> >
+ >
+ ,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<cds::gc::HP>
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,ci::opt::hook<
- ci::optimistic_queue::member_hook<
- offsetof(member_hook_item<cds::gc::HP>, hMember),
- ci::opt::gc<cds::gc::HP>
+ 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<cds::gc::HP>
+ >
>
- >
- ,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<cds::gc::HP>
- ,ci::opt::hook<
- ci::optimistic_queue::base_hook< ci::opt::gc<cds::gc::HP> >
- >
- ,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<cds::gc::HP> >
+ >
+ ,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<cds::gc::HP>
- ,ci::opt::hook<
- ci::optimistic_queue::member_hook<
- offsetof(member_hook_item<cds::gc::HP>, hMember),
- ci::opt::gc<cds::gc::HP>
+ 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<cds::gc::HP>
+ >
>
- >
- ,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)
+++ /dev/null
-//$$CDS-header$$
-
-#include "hdr_intrusive_msqueue.h"
-#include <cds/intrusive/optimistic_queue.h>
-#include <cds/gc/ptb.h>
-
-namespace queue {
-
-#define TEST(X) void IntrusiveQueueHeaderTest::test_##X() { test<X>(); }
-
- namespace {
- template <typename GC>
- struct base_hook_item: public ci::optimistic_queue::node< GC >
- {
- int nVal;
- int nDisposeCount;
-
- base_hook_item()
- : nDisposeCount(0)
- {}
- };
-
- template <typename GC>
- 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<cds::gc::PTB>
- ,ci::opt::hook<
- ci::optimistic_queue::base_hook< ci::opt::gc<cds::gc::PTB> >
- >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- > OptimisticQueue_PTB_base;
-
- // PTB member hook
- typedef ci::OptimisticQueue< cds::gc::PTB,
- member_hook_item<cds::gc::PTB>
- ,ci::opt::hook<
- ci::optimistic_queue::member_hook<
- offsetof(member_hook_item<cds::gc::PTB>, hMember),
- ci::opt::gc<cds::gc::PTB>
- >
- >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- > OptimisticQueue_PTB_member;
-
- /// PTB base hook + item counter
- typedef ci::OptimisticQueue< cds::gc::PTB,
- base_hook_item<cds::gc::PTB>
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,ci::opt::hook<
- ci::optimistic_queue::base_hook< ci::opt::gc<cds::gc::PTB> >
- >
- ,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<cds::gc::PTB>
- ,ci::opt::hook<
- ci::optimistic_queue::member_hook<
- offsetof(member_hook_item<cds::gc::PTB>, hMember),
- ci::opt::gc<cds::gc::PTB>
- >
- >
- ,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<cds::gc::PTB>
- ,ci::opt::hook<
- ci::optimistic_queue::base_hook< ci::opt::gc<cds::gc::PTB> >
- >
- ,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<cds::gc::PTB>
- ,ci::opt::hook<
- ci::optimistic_queue::member_hook<
- offsetof(member_hook_item<cds::gc::PTB>, hMember),
- ci::opt::gc<cds::gc::PTB>
- >
- >
- ,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<cds::gc::PTB>
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,ci::opt::hook<
- ci::optimistic_queue::base_hook< ci::opt::gc<cds::gc::PTB> >
- >
- ,co::alignment< 32 >
- > OptimisticQueue_PTB_base_align;
-
- // PTB member hook + alignment
- typedef ci::OptimisticQueue< cds::gc::PTB,
- member_hook_item<cds::gc::PTB>
- ,ci::opt::hook<
- ci::optimistic_queue::member_hook<
- offsetof(member_hook_item<cds::gc::PTB>, hMember),
- ci::opt::gc<cds::gc::PTB>
- >
- >
- ,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<cds::gc::PTB>
- ,ci::opt::hook<
- ci::optimistic_queue::base_hook< ci::opt::gc<cds::gc::PTB> >
- >
- ,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<cds::gc::PTB>
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,ci::opt::hook<
- ci::optimistic_queue::member_hook<
- offsetof(member_hook_item<cds::gc::PTB>, hMember),
- ci::opt::gc<cds::gc::PTB>
- >
- >
- ,co::alignment< co::no_special_alignment >
- > OptimisticQueue_PTB_member_noalign;
-
-
- // PTB base hook + cache alignment
- typedef ci::OptimisticQueue< cds::gc::PTB,
- base_hook_item<cds::gc::PTB>
- ,ci::opt::hook<
- ci::optimistic_queue::base_hook< ci::opt::gc<cds::gc::PTB> >
- >
- ,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<cds::gc::PTB>
- ,ci::opt::hook<
- ci::optimistic_queue::member_hook<
- offsetof(member_hook_item<cds::gc::PTB>, hMember),
- ci::opt::gc<cds::gc::PTB>
- >
- >
- ,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
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
// 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