#define __CDS_CONTAINER_BASKET_QUEUE_H
#include <memory>
-#include <functional> // ref
#include <cds/intrusive/basket_queue.h>
#include <cds/container/details/base.h>
-#include <cds/details/trivial_assign.h>
+//#include <cds/details/trivial_assign.h>
namespace cds { namespace container {
+ /// BasketQueue related definitions
+ /** @ingroup cds_nonintrusive_helper
+ */
+ namespace basket_queue {
+
+ /// Internal statistics
+ template <typename Counter = cds::intrusive::basket_queue::stat<>::counter_type >
+ using stat = cds::intrusive::basket_queue::stat< Counter >;
+
+ /// Dummy internal statistics
+ typedef cds::intrusive::basket_queue::empty_stat empty_stat;
+
+ /// BasketQueue default type traits
+ struct traits
+ {
+ /// Node allocator
+ typedef CDS_DEFAULT_ALLOCATOR allocator;
+
+ /// Back-off strategy
+ typedef cds::backoff::empty back_off;
+
+ /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter to enable item counting
+ typedef atomicity::empty_item_counter item_counter;
+
+ /// Internal statistics (by default, disabled)
+ /**
+ Possible option value are: \p basket_queue::stat, \p basket_queue::empty_stat (the default),
+ user-provided class that supports \p %basket_queue::stat interface.
+ */
+ typedef basket_queue::empty_stat stat;
+
+ /// C++ memory ordering model
+ /**
+ Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
+ or \p opt::v::sequential_consistent (sequentially consisnent memory model).
+ */
+ typedef opt::v::relaxed_ordering memory_model;
+
+ /// Alignment of internal queue data. Default is \p opt::cache_line_alignment
+ enum { alignment = opt::cache_line_alignment };
+ };
+
+ /// Metafunction converting option list to \p basket_queue::traits
+ /**
+ Supported \p Options are:
+ - opt::allocator - allocator (like \p std::allocator) used for allocating queue nodes. Default is \ref CDS_DEFAULT_ALLOCATOR
+ - opt::back_off - back-off strategy used, default is \p cds::backoff::empty.
+ - opt::item_counter - the type of item counting feature. Default is \p cds::atomicity::empty_item_counter (item counting disabled)
+ To enable item counting use \p cds::atomicity::item_counter
+ - opt::stat - the type to gather internal statistics.
+ Possible statistics types are: \p basket_queue::stat, \p basket_queue::empty_stat, user-provided class that supports \p %basket_queue::stat interface.
+ Default is \p %basket_queue::empty_stat.
+ - opt::alignment - the alignment for internal queue data. Default is \p opt::cache_line_alignment
+ - opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
+ or \p opt::v::sequential_consistent (sequentially consisnent memory model).
+
+ Example: declare \p %BasketQueue with item counting and internal statistics
+ \code
+ typedef cds::container::BasketQueue< cds::gc::HP, Foo,
+ typename cds::container::basket_queue::make_traits<
+ cds::opt::item_counte< cds::atomicity::item_counter >,
+ cds::opt::stat< cds::intrusive::basket_queue::stat<> >
+ >::type
+ > myQueue;
+ \endcode
+ */
+ template <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 basket_queue
+
//@cond
namespace details {
- template <typename GC, typename T, typename... Options>
+ template <typename GC, typename T, typename Traits>
struct make_basket_queue
{
typedef GC gc;
typedef T value_type;
-
- struct default_options {
- typedef cds::backoff::empty back_off;
- typedef CDS_DEFAULT_ALLOCATOR allocator;
- typedef atomicity::empty_item_counter item_counter;
- typedef intrusive::basket_queue::dummy_stat stat;
- typedef opt::v::relaxed_ordering memory_model;
- enum { alignment = opt::cache_line_alignment };
- };
-
- typedef typename opt::make_options<
- typename cds::opt::find_type_traits< default_options, Options... >::type
- ,Options...
- >::type options;
+ typedef Traits traits;
struct node_type: public intrusive::basket_queue::node< gc >
{
{}
};
- typedef typename options::allocator::template rebind<node_type>::other allocator_type;
+ typedef typename traits::allocator::template rebind<node_type>::other allocator_type;
typedef cds::details::Allocator< node_type, allocator_type > cxx_allocator;
struct node_deallocator
}
};
- typedef intrusive::BasketQueue< gc,
- node_type
- ,intrusive::opt::hook<
- intrusive::basket_queue::base_hook< opt::gc<gc> >
- >
- ,opt::back_off< typename options::back_off >
- ,intrusive::opt::disposer< node_deallocator >
- ,opt::item_counter< typename options::item_counter >
- ,opt::stat< typename options::stat >
- ,opt::alignment< options::alignment >
- ,opt::memory_model< typename options::memory_model >
- > type;
+ struct intrusive_traits : public traits
+ {
+ typedef intrusive::basket_queue::base_hook< opt::gc<gc> > hook;
+ typedef node_deallocator disposer;
+ };
+
+ typedef cds::intrusive::BasketQueue< gc, node_type, intrusive_traits > type;
};
}
//@endcond
Template arguments:
- - \p GC - garbage collector type: gc::HP, gc::HRC, gc::PTB
- - \p T is a type stored in the queue. It should be default-constructible, copy-constructible, assignable type.
- - \p Options - options
-
- Permissible \p Options:
- - opt::allocator - allocator (like \p std::allocator). Default is \ref CDS_DEFAULT_ALLOCATOR
- - opt::back_off - back-off strategy used. If the option is not specified, the cds::backoff::empty is used
- - opt::item_counter - the type of item counting feature. Default is \ref atomicity::empty_item_counter
- - opt::stat - the type to gather internal statistics for debugging and profiling purposes.
- Possible option value are: intrusive::basket_queue::stat, intrusive::basket_queue::dummy_stat (the default),
- user-provided class that supports intrusive::basket_queue::stat interface.
- Generic option intrusive::queue_stat and intrusive::queue_dummy_stat are acceptable too, however,
- they will be automatically converted to intrusive::basket_queue::stat and intrusive::basket_queue::dummy_stat
- respectively.
- - opt::alignment - the alignment for internal queue data. Default is opt::cache_line_alignment
- - opt::memory_model - C++ memory ordering model. Can be opt::v::relaxed_ordering (relaxed memory model, the default)
- or opt::v::sequential_consistent (sequentially consisnent memory model).
+ - \p GC - garbage collector type: \p gc::HP, \p gc::DHP
+ - \p T - type of value to be stored in the queue
+ - \p Traits - queue traits, default is \p basket_queue::traits. You can use \p basket_queue::make_traits
+ metafunction to make your traits or just derive your traits from \p %basket_queue::traits:
+ \code
+ struct myTraits: public cds::container::basket_queue::traits {
+ typedef cds::intrusive::basket_queue::stat<> stat;
+ typedef cds::atomicity::item_counter item_counter;
+ };
+ typedef cds::container::BasketQueue< cds::gc::HP, Foo, myTraits > myQueue;
+
+ // Equivalent make_traits example:
+ typedef cds::container::BasketQueue< cds::gc::HP, Foo,
+ typename cds::container::basket_queue::make_traits<
+ cds::opt::stat< cds::container::basket_queue::stat<> >,
+ cds::opt::item_counter< cds::atomicity::item_counter >
+ >::type
+ > myQueue;
+ \endcode
*/
- template <typename GC, typename T, typename... Options>
+ template <typename GC, typename T, typename Traits = basket_queue::traits >
class BasketQueue:
#ifdef CDS_DOXYGEN_INVOKED
- intrusive::BasketQueue< GC, intrusive::basket_queue::node< T >, Options... >
+ private intrusive::BasketQueue< GC, intrusive::basket_queue::node< T >, Traits >
#else
- details::make_basket_queue< GC, T, Options... >::type
+ protected details::make_basket_queue< GC, T, Traits >::type
#endif
{
//@cond
- typedef details::make_basket_queue< GC, T, Options... > options;
- typedef typename options::type base_class;
+ typedef details::make_basket_queue< GC, T, Options... > maker;
+ typedef typename maker::type base_class;
//@endcond
public:
/// Rebind template arguments
- template <typename GC2, typename T2, typename... Options2>
+ template <typename GC2, typename T2, typename Traits2>
struct rebind {
- typedef BasketQueue< GC2, T2, Options2...> other ; ///< Rebinding result
+ typedef BasketQueue< GC2, T2, Traits2> other ; ///< Rebinding result
};
public:
- typedef T value_type ; ///< Value type stored in the queue
+ typedef GC gc; ///< Garbage collector
+ typedef T value_type; ///< Type of value to be stored in the queue
+ typedef Traits traits; ///< Queue's traits
- typedef typename base_class::gc gc ; ///< Garbage collector used
- typedef typename base_class::back_off back_off ; ///< Back-off strategy used
- typedef typename options::allocator_type allocator_type ; ///< Allocator type used for allocate/deallocate the nodes
- typedef typename base_class::item_counter item_counter ; ///< Item counting policy used
- typedef typename base_class::stat stat ; ///< Internal statistics policy used
- typedef typename base_class::memory_model memory_model ; ///< Memory ordering. See cds::opt::memory_model option
+ typedef typename base_class::back_off back_off; ///< Back-off strategy used
+ typedef typename maker::allocator_type allocator_type; ///< Allocator type used for allocate/deallocate the nodes
+ typedef typename base_class::item_counter item_counter; ///< Item counting policy used
+ typedef typename base_class::stat stat; ///< Internal statistics policy used
+ typedef typename base_class::memory_model memory_model; ///< Memory ordering. See cds::opt::memory_model option
protected:
- typedef typename options::node_type node_type ; ///< queue node type (derived from intrusive::single_link::node)
+ typedef typename maker::node_type node_type; ///< queue node type (derived from intrusive::basket_queue::node)
//@cond
- typedef typename options::cxx_allocator cxx_allocator;
- typedef typename options::node_deallocator node_deallocator; // deallocate node
- typedef typename base_class::node_traits node_traits;
+ typedef typename maker::cxx_allocator cxx_allocator;
+ typedef typename maker::node_deallocator node_deallocator; // deallocate node
+ typedef typename base_class::node_traits node_traits;
//@endcond
protected:
free_node( pNode );
}
};
- typedef std::unique_ptr< node_type, node_disposer > scoped_node_ptr;
+ typedef std::unique_ptr< node_type, node_disposer > scoped_node_ptr;
//@endcond
public:
~BasketQueue()
{}
- /// Returns queue's item count
- /** \copydetails cds::intrusive::BasketQueue::size()
- */
- size_t size() const
- {
- return base_class::size();
- }
-
- /// Returns reference to internal statistics
- const stat& statistics() const
- {
- return base_class::statistics();
- }
-
/// Enqueues \p val value into the queue.
/**
The function makes queue node in dynamic memory calling copy constructor for \p val
- and then it calls intrusive::BasketQueue::enqueue.
+ and then it calls \p intrusive::BasketQueue::enqueue().
Returns \p true if success, \p false otherwise.
*/
- bool enqueue( const value_type& val )
+ bool enqueue( value_type const& val )
{
scoped_node_ptr p( alloc_node(val));
if ( base_class::enqueue( *p )) {
return false;
}
- /// Enqueues \p data to queue using copy functor
+ /// Enqueues \p data to queue using a functor
/**
- \p Func is a functor called to copy value \p data of type \p Type
- which may be differ from type \p T stored in the queue.
- The functor's interface is:
+ \p Func is a functor called to create node.
+ The functor \p f takes one argument - a reference to a new node of type \ref value_type :
\code
- struct myFunctor {
- void operator()(T& dest, Type const& data)
- {
- // // Code to copy \p data to \p dest
- dest = data;
- }
- };
+ cds::container::BasketQueue< cds::gc::HP, Foo > myQueue;
+ Bar bar;
+ myQueue.enqueue_with( [&bar]( Foo& dest ) { dest = bar; } );
\endcode
- You may use \p boost:ref construction to pass functor \p f by reference.
-
- <b>Requirements</b> The functor \p Func should not throw any exception.
*/
- template <typename Type, typename Func>
- bool enqueue( const Type& data, Func f )
+ template <typename Func>
+ bool enqueue_with( Func f )
{
- scoped_node_ptr p( alloc_node());
- f( p->m_value, data );
+ scoped_node_ptr p( alloc_node() );
+ f( p->m_value );
if ( base_class::enqueue( *p )) {
p.release();
return true;
return false;
}
+ /// Synonym for \p enqueue() function
+ bool push( const value_type& val )
+ {
+ return enqueue( val );
+ }
+
+ /// Synonym for \p enqueue_with() function
+ template <typename Func>
+ bool push_with( Func f )
+ {
+ return enqueue_with( f );
+ }
+
/// Enqueues data of type \ref value_type constructed with <tt>std::forward<Args>(args)...</tt>
template <typename... Args>
bool emplace( Args&&... args )
return false;
}
- /// Dequeues a value using copy functor
- /**
- \p Func is a functor called to copy dequeued value to \p dest of type \p Type
- which may be differ from type \p T stored in the queue.
- The functor's interface is:
- \code
- struct myFunctor {
- void operator()(Type& dest, T const& data)
- {
- // Code to copy \p data to \p dest
- dest = data;
- }
- };
- \endcode
- You may use \p boost:ref construction to pass functor \p f by reference.
-
- <b>Requirements</b> The functor \p Func should not throw any exception.
- */
- template <typename Type, typename Func>
- bool dequeue( Type& dest, Func f )
- {
- typename base_class::dequeue_result res;
- if ( base_class::do_dequeue( res, true )) {
- f( dest, node_traits::to_value_ptr( *res.pNext )->m_value );
- return true;
- }
- return false;
- }
-
/// Dequeues a value from the queue
/**
If queue is not empty, the function returns \p true, \p dest contains copy of
*/
bool dequeue( value_type& dest )
{
- typedef cds::details::trivial_assign<value_type, value_type> functor;
- return dequeue( dest, functor() );
+ return dequeue_with( [&dest]( value_type& src ) { dest = src; } );
}
- /// Synonym for \ref enqueue function
- bool push( const value_type& val )
- {
- return enqueue( val );
- }
-
- /// Synonym for template version of \ref enqueue function
- template <typename Type, typename Func>
- bool push( const Type& data, Func f )
+ /// Dequeues a value using a functor
+ /**
+ \p Func is a functor called to copy dequeued value.
+ The functor takes one argument - a reference to removed node:
+ \code
+ cds:container::BasketQueue< cds::gc::HP, Foo > myQueue;
+ Bar bar;
+ myQueue.dequeue_with( [&bar]( Foo& src ) { bar = std::move( src );});
+ \endcode
+ The functor is called only if the queue is not empty.
+ */
+ template <typename Func>
+ bool dequeue_with( Func f )
{
- return enqueue( data, f );
+ typename base_class::dequeue_result res;
+ if ( base_class::do_dequeue( res, true )) {
+ f( node_traits::to_value_ptr( *res.pNext )->m_value );
+ base_class::dispose_result( res );
+ return true;
+ }
+ return false;
}
- /// Synonym for \ref dequeue function
+ /// Synonym for \p dequeue() function
bool pop( value_type& dest )
{
return dequeue( dest );
}
- /// Synonym for template version of \ref dequeue function
- template <typename Type, typename Func>
- bool pop( Type& dest, Func f )
+ /// Synonym for \p dequeue_with() function
+ template <typename Func>
+ bool pop_with( Func f )
{
- return dequeue( dest, f );
+ return dequeue_with( f );
}
/// Checks if the queue is empty
/**
Note that this function is not \p const.
- The function is based on \ref dequeue algorithm.
+ The function is based on \p dequeue() algorithm.
*/
bool empty()
{
{
base_class::clear();
}
+
+ /// Returns queue's item count
+ /** \copydetails cds::intrusive::BasketQueue::size()
+ */
+ size_t size() const
+ {
+ return base_class::size();
+ }
+
+ /// Returns reference to internal statistics
+ const stat& statistics() const
+ {
+ return base_class::statistics();
+ }
+
};
}} // namespace cds::container
\p Func is a functor called to create node.
The functor \p f takes one argument - a reference to a new node of type \ref value_type :
\code
- cds:container::MSQueue< cds::gc::HP, Foo > myQueue;
+ cds::container::MSQueue< cds::gc::HP, Foo > myQueue;
Bar bar;
myQueue.enqueue_with( [&bar]( Foo& dest ) { dest = bar; } );
\endcode
#define __CDS_INTRUSIVE_BASKET_QUEUE_H
#include <type_traits>
-#include <functional> // ref
-#include <cds/intrusive/details/base.h>
-#include <cds/details/marked_ptr.h>
-#include <cds/intrusive/details/queue_stat.h>
#include <cds/intrusive/details/single_link_struct.h>
-#include <cds/intrusive/details/dummy_node_holder.h>
+#include <cds/details/marked_ptr.h>
namespace cds { namespace intrusive {
namespace basket_queue {
/// BasketQueue node
/**
+ Template parameters:
Template parameters:
- GC - garbage collector used
- - Tag - a tag used to distinguish between different implementation
- */
+ - Tag - a \ref cds_intrusive_hook_tag "tag"
+ */
template <class GC, typename Tag = opt::none>
- struct node: public GC::container_node
+ struct node
{
typedef GC gc ; ///< Garbage collector
typedef Tag tag ; ///< tag
- typedef cds::details::marked_ptr<node, 1> marked_ptr ; ///< marked pointer
- typedef typename gc::template atomic_marked_ptr< marked_ptr> atomic_marked_ptr ; ///< atomic marked pointer specific for GC
+ typedef cds::details::marked_ptr<node, 1> marked_ptr; ///< marked pointer
+ typedef typename gc::template atomic_marked_ptr< marked_ptr> atomic_marked_ptr; ///< atomic marked pointer specific for GC
/// Rebind node for other template parameters
template <class GC2, typename Tag2 = tag>
{}
};
- //@cond
- // Specialization for HRC GC
- template <typename Tag>
- struct node< gc::HRC, Tag>: public gc::HRC::container_node
- {
- typedef gc::HRC gc ; ///< Garbage collector
- typedef Tag tag ; ///< tag
-
- typedef cds::details::marked_ptr<node, 1> marked_ptr ; ///< marked pointer
- typedef typename gc::template atomic_marked_ptr< marked_ptr> atomic_marked_ptr ; ///< atomic marked pointer specific for GC
-
- atomic_marked_ptr m_pNext ; ///< pointer to the next node in the container
-
- node()
- : m_pNext( nullptr )
- {}
-
- protected:
- virtual void cleanUp( cds::gc::hrc::ThreadGC * pGC )
- {
- assert( pGC != nullptr );
- typename gc::template GuardArray<2> aGuards( *pGC );
-
- while ( true ) {
- marked_ptr pNext = aGuards.protect( 0, m_pNext );
- if ( pNext.ptr() && pNext->m_bDeleted.load(atomics::memory_order_acquire) ) {
- marked_ptr p = aGuards.protect( 1, pNext->m_pNext );
- m_pNext.compare_exchange_strong( pNext, p, atomics::memory_order_acquire, atomics::memory_order_relaxed );
- continue;
- }
- else {
- break;
- }
- }
- }
-
- virtual void terminate( cds::gc::hrc::ThreadGC * pGC, bool bConcurrent )
- {
- if ( bConcurrent ) {
- marked_ptr pNext = m_pNext.load(atomics::memory_order_relaxed);
- do {} while ( !m_pNext.compare_exchange_weak( pNext, marked_ptr(), atomics::memory_order_release, atomics::memory_order_relaxed ) );
- }
- else {
- m_pNext.store( marked_ptr(), atomics::memory_order_relaxed );
- }
- }
- };
- //@endcond
-
- using single_link::default_hook;
+ using cds::intrusive::single_link::default_hook;
//@cond
template < typename HookType, typename... Options>
/**
\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... >
\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... >
//@endcond
};
- /// Metafunction for selecting appropriate link checking policy
- template < typename Node, opt::link_check_type LinkType > using get_link_checker = single_link::get_link_checker< Node, LinkType >;
-
- /// Basket queue internal statistics. May be used for debugging or profiling
+ /// BasketQueue internal statistics. May be used for debugging or profiling
/**
- Basket queue statistics derives from cds::intrusive::queue_stat
- and extends it by two additional fields specific for the algorithm.
+ Template argument \p Counter defines type of counter.
+ Default is \p cds::atomicity::event_counter, that is weak, i.e. it is not guaranteed
+ strict event counting.
+ You may use stronger type of counter like as \p cds::atomicity::item_counter,
+ or even integral type, for example, \p int.
*/
template <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_TryAddBasket ; ///< Count of attemps adding new item to a basket (only or BasketQueue, for other queue this metric is not used)
- counter_type m_AddBasketCount ; ///< Count of events "Enqueue a new item into basket" (only or BasketQueue, for other queue this metric is not used)
-
+ typedef Counter counter_type; ///< Counter type
+
+ counter_type m_EnqueueCount; ///< Enqueue call count
+ counter_type m_DequeueCount; ///< Dequeue call count
+ counter_type m_EnqueueRace; ///< Count of enqueue race conditions encountered
+ counter_type m_DequeueRace; ///< Count of dequeue race conditions encountered
+ counter_type m_AdvanceTailError;///< Count of "advance tail failed" events
+ counter_type m_BadTail; ///< Count of events "Tail is not pointed to the last item in the queue"
+ counter_type m_TryAddBasket; ///< Count of attemps adding new item to a basket (only or BasketQueue, for other queue this metric is not used)
+ counter_type m_AddBasketCount; ///< Count of events "Enqueue a new item into basket" (only or BasketQueue, for other queue this metric is not used)
+
+ /// Register enqueue call
+ void onEnqueue() { ++m_EnqueueCount; }
+ /// Register dequeue call
+ void onDequeue() { ++m_DequeueCount; }
+ /// Register enqueue race event
+ void onEnqueueRace() { ++m_EnqueueRace; }
+ /// Register dequeue race event
+ void onDequeueRace() { ++m_DequeueRace; }
+ /// Register "advance tail failed" event
+ void onAdvanceTailFailed() { ++m_AdvanceTailError; }
+ /// Register event "Tail is not pointed to last item in the queue"
+ void onBadTail() { ++m_BadTail; }
/// Register an attempt t add new item to basket
void onTryAddBasket() { ++m_TryAddBasket; }
/// Register event "Enqueue a new item into basket" (only or BasketQueue, for other queue this metric is not used)
//@cond
void reset()
{
- base_class::reset();
+ m_EnqueueCount.reset();
+ m_DequeueCount.reset();
+ m_EnqueueRace.reset();
+ m_DequeueRace.reset();
+ m_AdvanceTailError.reset();
+ m_BadTail.reset();
m_TryAddBasket.reset();
m_AddBasketCount.reset();
}
stat& operator +=( stat const& s )
{
- base_class::operator +=( s );
- m_TryAddBasket += s.m_TryAddBasket.get();
+ m_EnqueueCount += s.m_EnqueueCount.get();
+ m_DequeueCount += s.m_DequeueCount.get();
+ m_EnqueueRace += s.m_EnqueueRace.get();
+ m_DequeueRace += s.m_DequeueRace.get();
+ m_AdvanceTailError += s.m_AdvanceTailError.get();
+ m_BadTail += s.m_BadTail.get();
+ m_TryAddBasket += s.m_TryAddBasket.get();
m_AddBasketCount += s.m_AddBasketCount.get();
return *this;
}
//@endcond
};
- /// Dummy basket queue statistics - no counting is performed. Support interface like \ref stat
- struct dummy_stat: public cds::intrusive::queue_dummy_stat
+ /// Dummy BasketQueue statistics - no counting is performed, no overhead. Support interface like \p basket_queue::stat
+ struct empty_stat
{
//@cond
- void onTryAddBasket() {}
- void onAddBasket() {}
+ void onEnqueue() {}
+ void onDequeue() {}
+ void onEnqueueRace() {}
+ void onDequeueRace() {}
+ void onAdvanceTailFailed() {}
+ void onBadTail() {}
+ void onTryAddBasket() {}
+ void onAddBasket() {}
void reset() {}
- dummy_stat& operator +=( dummy_stat const& )
+ empty_stat& operator +=( empty_stat const& )
{
return *this;
}
//@endcond
};
+ /// BasketQueue default type traits
+ struct traits
+ {
+ /// Back-off strategy
+ typedef cds::backoff::empty back_off;
+
+ /// Hook, possible types are \p basket_queue::base_hook, \p basket_queue::member_hook, \p basket_queue::traits_hook
+ typedef basket_queue::base_hook<> hook;
+
+ /// The functor used for dispose removed items. Default is \p opt::v::empty_disposer. This option is used for dequeuing
+ typedef opt::v::empty_disposer disposer;
+
+ /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter to enable item counting
+ typedef atomicity::empty_item_counter item_counter;
+
+ /// Internal statistics (by default, disabled)
+ /**
+ Possible option value are: \p basket_queue::stat, \p basket_queue::empty_stat (the default),
+ user-provided class that supports \p %basket_queue::stat interface.
+ */
+ typedef basket_queue::empty_stat stat;
+
+ /// C++ memory ordering model
+ /**
+ Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
+ or \p opt::v::sequential_consistent (sequentially consisnent memory model).
+ */
+ typedef opt::v::relaxed_ordering memory_model;
+
+ /// Link checking, see \p cds::opt::link_checker
+ static CDS_CONSTEXPR const opt::link_check_type link_checker = opt::debug_check_link;
+
+ /// Alignment for internal queue data. Default is \p opt::cache_line_alignment
+ enum { alignment = opt::cache_line_alignment };
+ };
+
+
+ /// Metafunction converting option list to \p basket_queue::traits
+ /**
+ Supported \p Options are:
+
+ - opt::hook - hook used. Possible hooks are: \p basket_queue::base_hook, \p basket_queue::member_hook, \p basket_queue::traits_hook.
+ If the option is not specified, \p %basket_queue::base_hook<> is used.
+ - opt::back_off - back-off strategy used, default is \p cds::backoff::empty.
+ - opt::disposer - the functor used for dispose removed items. Default is \p opt::v::empty_disposer. This option is used
+ when dequeuing.
+ - opt::link_checker - the type of node's link fields checking. Default is \p opt::debug_check_link
+ - opt::item_counter - the type of item counting feature. Default is \p cds::atomicity::empty_item_counter (item counting disabled)
+ To enable item counting use \p cds::atomicity::item_counter
+ - opt::stat - the type to gather internal statistics.
+ Possible statistics types are: \p basket_queue::stat, \p basket_queue::empty_stat, user-provided class that supports \p %basket_queue::stat interface.
+ Default is \p %basket_queue::empty_stat (internal statistics disabled).
+ - opt::alignment - the alignment for internal queue data. Default is \p opt::cache_line_alignment
+ - opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
+ or \p opt::v::sequential_consistent (sequentially consisnent memory model).
+
+ Example: declare \p %BasketQueue with item counting and internal statistics
+ \code
+ typedef cds::intrusive::BasketQueue< cds::gc::HP, Foo,
+ typename cds::intrusive::basket_queue::make_traits<
+ cds::intrusive::opt:hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc<cds:gc::HP> >>,
+ cds::opt::item_counte< cds::atomicity::item_counter >,
+ cds::opt::stat< cds::intrusive::basket_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 basket_queue
/// Basket lock-free queue (intrusive variant)
oldest basket. It may then dequeue any node in the oldest basket.
<b>Template arguments:</b>
- - \p GC - garbage collector type: gc::HP, gc::HRC, gc::PTB
- - \p T - type to be stored in the queue, should be convertible to \ref single_link::node
- - \p Options - options
-
- <b>Type of node</b>: \ref single_link::node
-
- \p Options are:
- - opt::hook - hook used. Possible values are: basket_queue::base_hook, basket_queue::member_hook, basket_queue::traits_hook.
- If the option is not specified, <tt>basket_queue::base_hook<></tt> is used.
- For Gidenstam's gc::HRC, only basket_queue::base_hook is supported.
- - opt::back_off - back-off strategy used. If the option is not specified, the cds::backoff::empty is used.
- - opt::disposer - the functor used for dispose removed items. Default is opt::v::empty_disposer. This option is used
- in \ref dequeue function.
- - opt::link_checker - the type of node's link fields checking. Default is \ref opt::debug_check_link
- Note: for gc::HRC garbage collector, link checking policy is always selected as \ref opt::always_check_link.
- - opt::item_counter - the type of item counting feature. Default is \ref atomicity::empty_item_counter (no item counting feature)
- - opt::stat - the type to gather internal statistics.
- Possible option value are: \ref basket_queue::stat, \ref basket_queue::dummy_stat,
- user-provided class that supports basket_queue::stat interface.
- Default is \ref basket_queue::dummy_stat.
- Generic option intrusive::queue_stat and intrusive::queue_dummy_stat are acceptable too, however,
- they will be automatically converted to basket_queue::stat and basket_queue::dummy_stat
- respectively.
- - opt::alignment - the alignment for internal queue data. Default is opt::cache_line_alignment
- - opt::memory_model - C++ memory ordering model. Can be opt::v::relaxed_ordering (relaxed memory model, the default)
- or opt::v::sequential_consistent (sequentially consisnent memory model).
-
- Garbage collecting schema \p GC must be consistent with the basket_queue::node GC.
+ - \p GC - garbage collector type: \p gc::HP, \p gc::DHP
+ - \p T - type of value to be stored in the queue
+ - \p Traits - queue traits, default is \p basket_queue::traits. You can use \p basket_queue::make_traits
+ metafunction to make your traits or just derive your traits from \p %basket_queue::traits:
+ \code
+ struct myTraits: public cds::intrusive::basket_queue::traits {
+ typedef cds::intrusive::basket_queue::stat<> stat;
+ typedef cds::atomicity::item_counter item_counter;
+ };
+ typedef cds::intrusive::BasketQueue< cds::gc::HP, Foo, myTraits > myQueue;
+
+ // Equivalent make_traits example:
+ typedef cds::intrusive::BasketQueue< cds::gc::HP, Foo,
+ typename cds::intrusive::basket_queue::make_traits<
+ cds::opt::stat< cds::intrusive::basket_queue::stat<> >,
+ cds::opt::item_counter< cds::atomicity::item_counter >
+ >::type
+ > myQueue;
+ \endcode
+
+ Garbage collecting schema \p GC must be consistent with the \p basket_queue::node GC.
\par About item disposing
- Like MSQueue, the Baskets queue algo has a key feature: even if the queue is empty it contains one item that is "dummy" one from
- the standpoint of the algo. See \ref dequeue function doc for explanation.
+ Like \p MSQueue, the Baskets queue algo has a key feature: even if the queue is empty it contains one item that is "dummy" one from
+ the standpoint of the algo. See \p dequeue() function doc for explanation.
\par Examples
\code
}
};
- typedef ci::BasketQueue< hp_gc,
- Foo
- ,ci::opt::hook<
- ci::basket_queue::base_hook< ci::opt::gc<hp_gc> >
- >
- ,ci::opt::disposer< fooDisposer >
- > fooQueue;
+ struct fooTraits: public ci::basket_queue::traits {
+ typedef ci::basket_queue::base_hook< ci::opt::gc<hp_gc> > hook;
+ typedef fooDisposer disposer;
+ };
+ typedef ci::BasketQueue< hp_gc, Foo, fooTraits > fooQueue;
// BasketQueue with Hazard Pointer garbage collector,
// member hook + item disposer + item counter,
ci::basket_queue::node< hp_gc > hMember;
};
- typedef ci::BasketQueue< hp_gc,
- Foo
- ,ci::opt::hook<
- ci::basket_queue::member_hook<
- offsetof(Bar, hMember)
- ,ci::opt::gc<hp_gc>
+ struct barTraits: public
+ ci::basket_queue::make_traits<
+ ci::opt::hook<
+ ci::basket_queue::member_hook<
+ offsetof(Bar, hMember)
+ ,ci::opt::gc<hp_gc>
+ >
>
- >
- ,ci::opt::disposer< fooDisposer >
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- ,cds::opt::alignment< cds::opt::no_special_alignment >
- > barQueue;
+ ,ci::opt::disposer< fooDisposer >
+ ,cds::opt::item_counter< cds::atomicity::item_counter >
+ ,cds::opt::alignment< cds::opt::no_special_alignment >
+ >::type
+ {};
+ typedef ci::BasketQueue< hp_gc, Bar, barTraits > barQueue;
\endcode
*/
- template <typename GC, typename T, typename... Options>
+ template <typename GC, typename T, typename Traits = basket_queue::traits >
class BasketQueue
{
- //@cond
- struct default_options
- {
- typedef cds::backoff::empty back_off;
- typedef basket_queue::base_hook<> hook;
- typedef opt::v::empty_disposer disposer;
- typedef atomicity::empty_item_counter item_counter;
- typedef basket_queue::dummy_stat stat;
- typedef opt::v::relaxed_ordering memory_model;
- static const opt::link_check_type link_checker = opt::debug_check_link;
- enum { alignment = opt::cache_line_alignment };
- };
- //@endcond
-
public:
- //@cond
- typedef typename opt::make_options<
- typename cds::opt::find_type_traits< default_options, Options... >::type
- ,Options...
- >::type options;
-
- typedef typename std::conditional<
- std::is_same<typename options::stat, cds::intrusive::queue_stat<> >::value
- ,basket_queue::stat<>
- ,typename std::conditional<
- std::is_same<typename options::stat, cds::intrusive::queue_dummy_stat>::value
- ,basket_queue::dummy_stat
- ,typename options::stat
- >::type
- >::type stat_type_;
-
- //@endcond
-
- public:
- typedef T value_type ; ///< type of value stored in the queue
- typedef typename options::hook hook ; ///< hook type
- typedef typename hook::node_type node_type ; ///< node type
- typedef typename options::disposer disposer ; ///< disposer used
- typedef typename get_node_traits< value_type, node_type, hook>::type node_traits ; ///< node traits
- typedef typename basket_queue::get_link_checker< node_type, options::link_checker >::type link_checker ; ///< link checker
-
- typedef GC gc ; ///< Garbage collector
- typedef typename options::back_off back_off ; ///< back-off strategy
- typedef typename options::item_counter item_counter ; ///< Item counting policy used
-#ifdef CDS_DOXYGEN_INVOKED
- typedef typename options::stat stat ; ///< Internal statistics policy used
-#else
- typedef stat_type_ stat;
-#endif
- typedef typename options::memory_model memory_model ; ///< Memory ordering. See cds::opt::memory_model option
+ typedef GC gc; ///< Garbage collector
+ typedef T value_type; ///< type of value stored in the queue
+ typedef Traits traits; ///< Queue traits
+ typedef typename traits::hook hook; ///< hook type
+ typedef typename hook::node_type node_type; ///< node type
+ typedef typename traits::disposer disposer; ///< disposer used
+ typedef typename get_node_traits< value_type, node_type, hook>::type node_traits; ///< node traits
+ typedef typename single_link::get_link_checker< node_type, traits::link_checker >::type link_checker; ///< link checker
+
+ typedef typename traits::back_off back_off; ///< back-off strategy
+ typedef typename traits::item_counter item_counter; ///< Item counting policy used
+ typedef typename traits::stat stat; ///< Internal statistics policy used
+ typedef typename traits::memory_model memory_model; ///< Memory ordering. See cds::opt::memory_model option
/// Rebind template arguments
- template <typename GC2, typename T2, typename... Options2>
+ template <typename GC2, typename T2, typename Traits2>
struct rebind {
- typedef BasketQueue< GC2, T2, Options2...> other ; ///< Rebinding result
+ typedef BasketQueue< GC2, T2, Traits2> other ; ///< Rebinding result
};
- static const size_t m_nHazardPtrCount = 6 ; ///< Count of hazard pointer required for the algorithm
+ static CDS_CONSTEXPR const size_t m_nHazardPtrCount = 6 ; ///< Count of hazard pointer required for the algorithm
protected:
//@cond
-
- struct internal_disposer
- {
- void operator()( value_type * p )
- {
- assert( p != nullptr );
-
- BasketQueue::clear_links( node_traits::to_node_ptr(p) );
- disposer()( p );
- }
- };
-
typedef typename node_type::marked_ptr marked_ptr;
typedef typename node_type::atomic_marked_ptr atomic_marked_ptr;
typedef intrusive::node_to_value<BasketQueue> node_to_value;
- typedef typename opt::details::alignment_setter< atomic_marked_ptr, options::alignment >::type aligned_node_ptr;
- typedef typename opt::details::alignment_setter<
- cds::intrusive::details::dummy_node< gc, node_type>,
- options::alignment
- >::type dummy_node_type;
+ typedef typename opt::details::alignment_setter< atomic_marked_ptr, traits::alignment >::type aligned_node_ptr;
+ typedef typename opt::details::alignment_setter< node_type, options::alignment >::type dummy_node_type;
+ // GC and node_type::gc must be the same
+ static_assert( std::is_same<gc, typename node_type::gc>::value, "GC and node_type::gc must be the same");
//@endcond
aligned_node_ptr m_pHead ; ///< Queue's head pointer (aligned)
aligned_node_ptr m_pTail ; ///< Queue's tail pointer (aligned)
-
dummy_node_type m_Dummy ; ///< dummy node
item_counter m_ItemCounter ; ///< Item counter
stat m_Stat ; ///< Internal statistics
void dispose_node( node_type * p )
{
if ( p != m_Dummy.get() ) {
+ struct internal_disposer
+ {
+ void operator()( value_type * p )
+ {
+ assert( p != nullptr );
+ BasketQueue::clear_links( node_traits::to_node_ptr( p ) );
+ disposer()(p);
+ }
+ };
gc::template retire<internal_disposer>( node_traits::to_value_ptr(p) );
}
else
public:
/// Initializes empty queue
BasketQueue()
- : m_pHead( nullptr )
- , m_pTail( nullptr )
+ : m_pHead( &m_Dummy )
+ , m_pTail( &m_Dummy )
, m_nMaxHops( 3 )
- {
- // GC and node_type::gc must be the same
- static_assert(( std::is_same<gc, typename node_type::gc>::value ), "GC and node_type::gc must be the same");
-
- // For cds::gc::HRC, only one base_hook is allowed
- static_assert((
- std::conditional<
- std::is_same<gc, cds::gc::HRC>::value,
- std::is_same< typename hook::hook_type, opt::base_hook_tag >,
- boost::true_type
- >::type::value
- ), "For cds::gc::HRC, only base_hook is allowed");
-
- // Head/tail initialization should be made via store call
- // because of gc::HRC manages reference counting
- m_pHead.store( marked_ptr(m_Dummy.get()), memory_model::memory_order_relaxed );
- m_pTail.store( marked_ptr(m_Dummy.get()), memory_model::memory_order_relaxed );
- }
+ {}
/// Destructor clears the queue
/**
dispose_node( pHead );
}
- /// Returns queue's item count
- /**
- The value returned depends on opt::item_counter option. For atomicity::empty_item_counter,
- this function always returns 0.
-
- <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.
- */
- size_t size() const
- {
- return m_ItemCounter.value();
- }
-
- /// Returns reference to internal statistics
- const stat& statistics() const
- {
- return m_Stat;
- }
-
/// Enqueues \p val value into the queue.
/** @anchor cds_intrusive_BasketQueue_enqueue
The function always returns \p true.
return true;
}
+ /// Synonym for \p enqueue() function
+ bool push( value_type& val )
+ {
+ return enqueue( val );
+ }
+
/// Dequeues a value from the queue
/** @anchor cds_intrusive_BasketQueue_dequeue
If the queue is empty the function returns \p nullptr.
- <b>Warning</b>: see MSQueue::deque note about item disposing
+ @note See \p MSQueue::dequeue() note about item disposing
*/
value_type * dequeue()
{
return nullptr;
}
- /// Synonym for \ref cds_intrusive_BasketQueue_enqueue "enqueue" function
- bool push( value_type& val )
- {
- return enqueue( val );
- }
-
- /// Synonym for \ref cds_intrusive_BasketQueue_dequeue "dequeue" function
+ /// Synonym for \p dequeue() function
value_type * pop()
{
return dequeue();
/// Checks if the queue is empty
/**
Note that this function is not \p const.
- The function is based on \ref dequeue algorithm
- but really does not dequeued any item.
+ The function is based on \p dequeue() algorithm
+ but really it does not dequeue any item.
*/
bool empty()
{
/// Clear the queue
/**
- The function repeatedly calls \ref dequeue until it returns \p nullptr.
- The disposer defined in template \p Options is called for each item
+ The function repeatedly calls \p dequeue() until it returns \p nullptr.
+ The disposer defined in template \p Traits is called for each item
that can be safely disposed.
*/
void clear()
{
while ( dequeue() );
}
+
+ /// Returns queue's item count
+ /**
+ The value returned depends on \p Traits (see basket_queue::traits::item_counter). For \p atomicity::empty_item_counter,
+ this function always returns 0.
+
+ @note Even if you use real item counter and it returns 0, this fact is not mean that the queue
+ is empty. To check queue emptyness use \p empty() method.
+ */
+ size_t size() const
+ {
+ return m_ItemCounter.value();
+ }
+
+ /// Returns reference to internal statistics
+ const stat& statistics() const
+ {
+ return m_Stat;
+ }
};
}} // namespace cds::intrusive
template <typename Counter = cds::atomicity::event_counter >
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
};
/// Dummy queue statistics - no counting is performed, no overhead. Support interface like \p msqueue::stat
- /** @ingroup cds_intrusive_helper
- */
struct empty_stat
{
//@cond
/// Link checking, see \p cds::opt::link_checker
static CDS_CONSTEXPR const opt::link_check_type link_checker = opt::debug_check_link;
- /// Alignment of internal queue data. Default is \p opt::cache_line_alignment
+ /// Alignment for internal queue data. Default is \p opt::cache_line_alignment
enum { alignment = opt::cache_line_alignment };
};
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).
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
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
</Link>\r
</ItemDefinitionGroup>\r
<ItemGroup>\r
- <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_basketqueue_hrc.cpp" />\r
- <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_basketqueue_hzp.cpp" />\r
- <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_basketqueue_ptb.cpp" />\r
+ <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_basketqueue_dhp.cpp" />\r
+ <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_basketqueue_hp.cpp" />\r
<ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_fcqueue.cpp" />\r
+ <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_basketqueue_dhp.cpp" />\r
<ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_fcqueue.cpp" />\r
<ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_basketqueue_hp.cpp" />\r
- <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_basketqueue_hrc.cpp" />\r
- <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_basketqueue_ptb.cpp" />\r
<ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_moirqueue_dhp.cpp" />\r
<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_vyukov_mpmc_cyclic.cpp" />\r
</ItemGroup>\r
<ItemGroup>\r
- <ClInclude Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_basketqueue_node.h" />\r
<ClInclude Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_msqueue.h" />\r
<ClInclude Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_segmented_queue.h" />\r
<ClInclude Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_singlelink_node.h" />\r
<?xml version="1.0" encoding="utf-8"?>\r
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
<ItemGroup>\r
- <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_basketqueue_hrc.cpp">\r
- <Filter>container</Filter>\r
- </ClCompile>\r
- <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_basketqueue_hzp.cpp">\r
- <Filter>container</Filter>\r
- </ClCompile>\r
- <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_basketqueue_ptb.cpp">\r
- <Filter>container</Filter>\r
- </ClCompile>\r
<ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_fcqueue.cpp">\r
<Filter>container</Filter>\r
</ClCompile>\r
<ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_basketqueue_hp.cpp">\r
<Filter>intrusive</Filter>\r
</ClCompile>\r
- <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_basketqueue_hrc.cpp">\r
- <Filter>intrusive</Filter>\r
- </ClCompile>\r
- <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_basketqueue_ptb.cpp">\r
- <Filter>intrusive</Filter>\r
- </ClCompile>\r
<ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_fcqueue.cpp">\r
<Filter>intrusive</Filter>\r
</ClCompile>\r
<Filter>container</Filter>\r
</ClCompile>\r
<ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_queue_register.cpp" />\r
+ <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_basketqueue_dhp.cpp">\r
+ <Filter>intrusive</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_basketqueue_dhp.cpp">\r
+ <Filter>container</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\tests\test-hdr\queue\hdr_basketqueue_hp.cpp">\r
+ <Filter>container</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
- <ClInclude Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_basketqueue_node.h">\r
- <Filter>intrusive</Filter>\r
- </ClInclude>\r
<ClInclude Include="..\..\..\tests\test-hdr\queue\hdr_intrusive_msqueue.h">\r
<Filter>intrusive</Filter>\r
</ClInclude>\r
CDS_TESTHDR_QUEUE := \
tests/test-hdr/queue/hdr_queue_register.cpp \
- tests/test-hdr/queue/hdr_intrusive_basketqueue_hrc.cpp \
tests/test-hdr/queue/hdr_intrusive_fcqueue.cpp \
tests/test-hdr/queue/hdr_intrusive_segmented_queue_hp.cpp \
tests/test-hdr/queue/hdr_intrusive_segmented_queue_ptb.cpp \
tests/test-hdr/queue/hdr_intrusive_tsigas_cycle_queue.cpp \
tests/test-hdr/queue/hdr_intrusive_vyukovmpmc_cycle_queue.cpp \
- tests/test-hdr/queue/hdr_basketqueue_hrc.cpp \
- tests/test-hdr/queue/hdr_basketqueue_hzp.cpp \
- tests/test-hdr/queue/hdr_basketqueue_ptb.cpp \
+ tests/test-hdr/queue/hdr_basketqueue_hp.cpp \
+ tests/test-hdr/queue/hdr_basketqueue_dhp.cpp \
tests/test-hdr/queue/hdr_fcqueue.cpp \
tests/test-hdr/queue/hdr_moirqueue_hp.cpp \
tests/test-hdr/queue/hdr_moirqueue_dhp.cpp \
CDS_TESTHDR_OFFSETOF_QUEUE := \
tests/test-hdr/queue/hdr_intrusive_basketqueue_hp.cpp \
- tests/test-hdr/queue/hdr_intrusive_basketqueue_ptb.cpp \
+ tests/test-hdr/queue/hdr_intrusive_basketqueue_dhp.cpp \
tests/test-hdr/queue/hdr_intrusive_moirqueue_hp.cpp \
tests/test-hdr/queue/hdr_intrusive_moirqueue_dhp.cpp \
tests/test-hdr/queue/hdr_intrusive_msqueue_hp.cpp \
--- /dev/null
+//$$CDS-header$$
+
+#include <cds/gc/dhp.h>
+#include <cds/container/basket_queue.h>
+
+#include "queue/hdr_queue_new.h"
+
+namespace queue {
+
+ void HdrTestQueue::BasketQueue_DHP()
+ {
+ typedef cds::container::BasketQueue< cds::gc::DHP, int > queue_type;
+ test_no_ic< queue_type >();
+ }
+
+ void HdrTestQueue::BasketQueue_DHP_Counted()
+ {
+ struct traits : public cds::container::basket_queue::traits
+ {
+ typedef cds::atomicity::item_counter item_counter;
+ };
+ typedef cds::container::BasketQueue< cds::gc::DHP, int, traits > queue_type;
+ test_ic< queue_type >();
+ }
+
+ void HdrTestQueue::BasketQueue_DHP_relax()
+ {
+ struct traits : public
+ cds::container::basket_queue::make_traits <
+ cds::opt::memory_model< cds::opt::v::relaxed_ordering>
+ > ::type
+ {};
+ typedef cds::container::BasketQueue< cds::gc::DHP, int, traits > queue_type;
+ test_no_ic< queue_type >();
+ }
+
+ void HdrTestQueue::BasketQueue_DHP_Counted_relax()
+ {
+ typedef cds::container::BasketQueue< cds::gc::DHP, int,
+ typename cds::container::basket_queue::make_traits <
+ cds::opt::item_counter< cds::atomicity::item_counter >
+ ,cds::opt::memory_model< cds::opt::v::relaxed_ordering>
+ >::type
+ > queue_type;
+ test_ic< queue_type >();
+ }
+
+ void HdrTestQueue::BasketQueue_DHP_seqcst()
+ {
+ struct traits : public cds::container::basket_queue::traits
+ {
+ typedef cds::opt::v::sequential_consistent memory_model;
+ };
+ typedef cds::container::BasketQueue< cds::gc::DHP, int, traits > queue_type;
+ test_no_ic< queue_type >();
+ }
+
+ void HdrTestQueue::BasketQueue_DHP_Counted_seqcst()
+ {
+ typedef cds::container::BasketQueue < cds::gc::DHP, int,
+ typename cds::container::basket_queue::make_traits <
+ cds::opt::item_counter< cds::atomicity::item_counter >
+ ,cds::opt::memory_model< cds::opt::v::sequential_consistent>
+ >::type
+ > queue_type;
+ test_ic< queue_type >();
+ }
+
+ void HdrTestQueue::BasketQueue_DHP_relax_align()
+ {
+ typedef cds::container::BasketQueue < cds::gc::DHP, int,
+ typename cds::container::basket_queue::make_traits <
+ cds::opt::memory_model< cds::opt::v::relaxed_ordering>
+ ,cds::opt::alignment< 16 >
+ >::type
+ > queue_type;
+ test_ic< queue_type >();
+ }
+
+ void HdrTestQueue::BasketQueue_DHP_Counted_relax_align()
+ {
+ struct traits : public cds::container::basket_queue::traits
+ {
+ typedef cds::atomicity::item_counter item_counter;
+ typedef cds::opt::v::relaxed_ordering memory_model;
+ enum { alignment = 32 };
+ };
+ typedef cds::container::BasketQueue < cds::gc::DHP, int, traits > queue_type;
+ test_ic< queue_type >( 0 );
+ }
+
+ void HdrTestQueue::BasketQueue_DHP_seqcst_align()
+ {
+ typedef cds::container::BasketQueue < cds::gc::DHP, int,
+ typename cds::container::basket_queue::make_traits <
+ cds::opt::memory_model< cds::opt::v::sequential_consistent>
+ , cds::opt::alignment< cds::opt::no_special_alignment >
+ > ::type
+ > queue_type;
+ test_no_ic< queue_type >();
+ }
+
+ void HdrTestQueue::BasketQueue_DHP_Counted_seqcst_align()
+ {
+ typedef cds::container::BasketQueue < cds::gc::DHP, int,
+ typename cds::container::basket_queue::make_traits <
+ cds::opt::item_counter< cds::atomicity::item_counter >
+ ,cds::opt::memory_model< cds::opt::v::sequential_consistent>
+ ,cds::opt::alignment< cds::opt::cache_line_alignment >
+ > ::type
+ > queue_type;
+ test_no_ic< queue_type >();
+ }
+
+} // namespace queue
--- /dev/null
+//$$CDS-header$$
+
+#include <cds/gc/hp.h>
+#include <cds/container/basket_queue.h>
+
+#include "queue/hdr_queue_new.h"
+
+namespace queue {
+
+ void HdrTestQueue::BasketQueue_HP()
+ {
+ typedef cds::container::BasketQueue< cds::gc::HP, int > queue_type;
+ test_no_ic< queue_type >();
+ }
+
+ void HdrTestQueue::BasketQueue_HP_Counted()
+ {
+ struct traits : public cds::container::basket_queue::traits
+ {
+ typedef cds::atomicity::item_counter item_counter;
+ };
+ typedef cds::container::BasketQueue< cds::gc::HP, int, traits > queue_type;
+ test_ic< queue_type >();
+ }
+
+ void HdrTestQueue::BasketQueue_HP_relax()
+ {
+ struct traits : public
+ cds::container::basket_queue::make_traits <
+ cds::opt::memory_model< cds::opt::v::relaxed_ordering>
+ > ::type
+ {};
+ typedef cds::container::BasketQueue< cds::gc::HP, int, traits > queue_type;
+ test_no_ic< queue_type >();
+ }
+
+ void HdrTestQueue::BasketQueue_HP_Counted_relax()
+ {
+ typedef cds::container::BasketQueue< cds::gc::HP, int,
+ typename cds::container::basket_queue::make_traits <
+ cds::opt::item_counter< cds::atomicity::item_counter >
+ ,cds::opt::memory_model< cds::opt::v::relaxed_ordering>
+ >::type
+ > queue_type;
+ test_ic< queue_type >();
+ }
+
+ void HdrTestQueue::BasketQueue_HP_seqcst()
+ {
+ struct traits : public cds::container::basket_queue::traits
+ {
+ typedef cds::opt::v::sequential_consistent memory_model;
+ };
+ typedef cds::container::BasketQueue< cds::gc::HP, int, traits > queue_type;
+ test_no_ic< queue_type >();
+ }
+
+ void HdrTestQueue::BasketQueue_HP_Counted_seqcst()
+ {
+ typedef cds::container::BasketQueue < cds::gc::HP, int,
+ typename cds::container::basket_queue::make_traits <
+ cds::opt::item_counter< cds::atomicity::item_counter >
+ ,cds::opt::memory_model< cds::opt::v::sequential_consistent>
+ >::type
+ > queue_type;
+ test_ic< queue_type >();
+ }
+
+ void HdrTestQueue::BasketQueue_HP_relax_align()
+ {
+ typedef cds::container::BasketQueue < cds::gc::HP, int,
+ typename cds::container::basket_queue::make_traits <
+ cds::opt::memory_model< cds::opt::v::relaxed_ordering>
+ ,cds::opt::alignment< 16 >
+ >::type
+ > queue_type;
+ test_ic< queue_type >();
+ }
+
+ void HdrTestQueue::BasketQueue_HP_Counted_relax_align()
+ {
+ struct traits : public cds::container::basket_queue::traits
+ {
+ typedef cds::atomicity::item_counter item_counter;
+ typedef cds::opt::v::relaxed_ordering memory_model;
+ enum { alignment = 32 };
+ };
+ typedef cds::container::BasketQueue < cds::gc::HP, int, traits > queue_type;
+ test_ic< queue_type >( 0 );
+ }
+
+ void HdrTestQueue::BasketQueue_HP_seqcst_align()
+ {
+ typedef cds::container::BasketQueue < cds::gc::HP, int,
+ typename cds::container::basket_queue::make_traits <
+ cds::opt::memory_model< cds::opt::v::sequential_consistent>
+ , cds::opt::alignment< cds::opt::no_special_alignment >
+ > ::type
+ > queue_type;
+ test_no_ic< queue_type >();
+ }
+
+ void HdrTestQueue::BasketQueue_HP_Counted_seqcst_align()
+ {
+ typedef cds::container::BasketQueue < cds::gc::HP, int,
+ typename cds::container::basket_queue::make_traits <
+ cds::opt::item_counter< cds::atomicity::item_counter >
+ ,cds::opt::memory_model< cds::opt::v::sequential_consistent>
+ ,cds::opt::alignment< cds::opt::cache_line_alignment >
+ > ::type
+ > queue_type;
+ test_no_ic< queue_type >();
+ }
+
+} // namespace queue
+++ /dev/null
-//$$CDS-header$$
-
-#include <cds/container/basket_queue.h>
-#include <cds/gc/hrc.h>
-
-#include "queue/hdr_queue.h"
-
-namespace queue {
-
- void Queue_TestHeader::BasketQueue_HRC()
- {
- testNoItemCounter<
- cds::container::BasketQueue< cds::gc::HRC, int
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_HRC_Counted()
- {
- testWithItemCounter<
- cds::container::BasketQueue< cds::gc::HRC, int
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_HRC_relax()
- {
- testNoItemCounter<
- cds::container::BasketQueue< cds::gc::HRC, int
- ,cds::opt::memory_model< cds::opt::v::relaxed_ordering>
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_HRC_Counted_relax()
- {
- testWithItemCounter<
- cds::container::BasketQueue< cds::gc::HRC, int
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- ,cds::opt::memory_model< cds::opt::v::relaxed_ordering>
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_HRC_seqcst()
- {
- testNoItemCounter<
- cds::container::BasketQueue< cds::gc::HRC, int
- ,cds::opt::memory_model< cds::opt::v::sequential_consistent>
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_HRC_Counted_seqcst()
- {
- testWithItemCounter<
- cds::container::BasketQueue< cds::gc::HRC, int
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- ,cds::opt::memory_model< cds::opt::v::sequential_consistent>
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_HRC_relax_align()
- {
- testNoItemCounter<
- cds::container::BasketQueue< cds::gc::HRC, int
- ,cds::opt::memory_model< cds::opt::v::relaxed_ordering>
- ,cds::opt::alignment< 16 >
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_HRC_Counted_relax_align()
- {
- testWithItemCounter<
- cds::container::BasketQueue< cds::gc::HRC, int
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- ,cds::opt::memory_model< cds::opt::v::relaxed_ordering>
- ,cds::opt::alignment< 32 >
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_HRC_seqcst_align()
- {
- testNoItemCounter<
- cds::container::BasketQueue< cds::gc::HRC, int
- ,cds::opt::memory_model< cds::opt::v::sequential_consistent>
- ,cds::opt::alignment< cds::opt::no_special_alignment >
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_HRC_Counted_seqcst_align()
- {
- testWithItemCounter<
- cds::container::BasketQueue< cds::gc::HRC, int
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- ,cds::opt::memory_model< cds::opt::v::sequential_consistent>
- ,cds::opt::alignment< cds::opt::cache_line_alignment >
- >
- >();
- }
-
-} // namespace queue
+++ /dev/null
-//$$CDS-header$$
-
-#include <cds/container/basket_queue.h>
-#include <cds/gc/hp.h>
-
-#include "queue/hdr_queue.h"
-
-namespace queue {
-
- void Queue_TestHeader::BasketQueue_HP()
- {
- testNoItemCounter<
- cds::container::BasketQueue< cds::gc::HP, int
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_HP_Counted()
- {
- testWithItemCounter<
- cds::container::BasketQueue< cds::gc::HP, int
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_HP_relax()
- {
- testNoItemCounter<
- cds::container::BasketQueue< cds::gc::HP, int
- ,cds::opt::memory_model< cds::opt::v::relaxed_ordering>
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_HP_Counted_relax()
- {
- testWithItemCounter<
- cds::container::BasketQueue< cds::gc::HP, int
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- ,cds::opt::memory_model< cds::opt::v::relaxed_ordering>
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_HP_seqcst()
- {
- testNoItemCounter<
- cds::container::BasketQueue< cds::gc::HP, int
- ,cds::opt::memory_model< cds::opt::v::sequential_consistent>
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_HP_Counted_seqcst()
- {
- testWithItemCounter<
- cds::container::BasketQueue< cds::gc::HP, int
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- ,cds::opt::memory_model< cds::opt::v::sequential_consistent>
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_HP_relax_align()
- {
- testNoItemCounter<
- cds::container::BasketQueue< cds::gc::HP, int
- ,cds::opt::memory_model< cds::opt::v::relaxed_ordering>
- ,cds::opt::alignment< 16 >
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_HP_Counted_relax_align()
- {
- testWithItemCounter<
- cds::container::BasketQueue< cds::gc::HP, int
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- ,cds::opt::memory_model< cds::opt::v::relaxed_ordering>
- ,cds::opt::alignment< 32 >
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_HP_seqcst_align()
- {
- testNoItemCounter<
- cds::container::BasketQueue< cds::gc::HP, int
- ,cds::opt::memory_model< cds::opt::v::sequential_consistent>
- ,cds::opt::alignment< cds::opt::no_special_alignment >
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_HP_Counted_seqcst_align()
- {
- testWithItemCounter<
- cds::container::BasketQueue< cds::gc::HP, int
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- ,cds::opt::memory_model< cds::opt::v::sequential_consistent>
- ,cds::opt::alignment< cds::opt::cache_line_alignment >
- >
- >();
- }
-
-} // namespace queue
+++ /dev/null
-//$$CDS-header$$
-
-#include <cds/container/basket_queue.h>
-#include <cds/gc/ptb.h>
-
-#include "queue/hdr_queue.h"
-
-namespace queue {
-
- void Queue_TestHeader::BasketQueue_PTB()
- {
- testNoItemCounter<
- cds::container::BasketQueue< cds::gc::PTB, int
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_PTB_Counted()
- {
- testWithItemCounter<
- cds::container::BasketQueue< cds::gc::PTB, int
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_PTB_relax()
- {
- testNoItemCounter<
- cds::container::BasketQueue< cds::gc::PTB, int
- ,cds::opt::memory_model< cds::opt::v::relaxed_ordering>
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_PTB_Counted_relax()
- {
- testWithItemCounter<
- cds::container::BasketQueue< cds::gc::PTB, int
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- ,cds::opt::memory_model< cds::opt::v::relaxed_ordering>
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_PTB_seqcst()
- {
- testNoItemCounter<
- cds::container::BasketQueue< cds::gc::PTB, int
- ,cds::opt::memory_model< cds::opt::v::sequential_consistent>
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_PTB_Counted_seqcst()
- {
- testWithItemCounter<
- cds::container::BasketQueue< cds::gc::PTB, int
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- ,cds::opt::memory_model< cds::opt::v::sequential_consistent>
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_PTB_relax_align()
- {
- testNoItemCounter<
- cds::container::BasketQueue< cds::gc::PTB, int
- ,cds::opt::memory_model< cds::opt::v::relaxed_ordering>
- ,cds::opt::alignment< 16 >
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_PTB_Counted_relax_align()
- {
- testWithItemCounter<
- cds::container::BasketQueue< cds::gc::PTB, int
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- ,cds::opt::memory_model< cds::opt::v::relaxed_ordering>
- ,cds::opt::alignment< 32 >
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_PTB_seqcst_align()
- {
- testNoItemCounter<
- cds::container::BasketQueue< cds::gc::PTB, int
- ,cds::opt::memory_model< cds::opt::v::sequential_consistent>
- ,cds::opt::alignment< cds::opt::no_special_alignment >
- >
- >();
- }
-
- void Queue_TestHeader::BasketQueue_PTB_Counted_seqcst_align()
- {
- testWithItemCounter<
- cds::container::BasketQueue< cds::gc::PTB, int
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- ,cds::opt::memory_model< cds::opt::v::sequential_consistent>
- ,cds::opt::alignment< cds::opt::cache_line_alignment >
- >
- >();
- }
-
-} // namespace queue
--- /dev/null
+//$$CDS-header$$
+
+#include "hdr_intrusive_msqueue.h"
+#include <cds/gc/dhp.h>
+#include <cds/intrusive/basket_queue.h>
+
+namespace queue {
+
+#define TEST(X) void IntrusiveQueueHeaderTest::test_##X() { test_basket<X>(); }
+
+ namespace {
+ typedef IntrusiveQueueHeaderTest::base_hook_item < ci::basket_queue::node<cds::gc::DHP> > base_hook_item;
+ typedef IntrusiveQueueHeaderTest::member_hook_item < ci::basket_queue::node<cds::gc::DHP> > member_hook_item;
+
+ // DHP base hook
+ struct traits_BasketQueue_disposer : public
+ ci::basket_queue::make_traits < ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer > >::type
+ {
+ typedef ci::basket_queue::base_hook< ci::opt::gc < cds::gc::DHP > > hook;
+ };
+ typedef ci::BasketQueue< cds::gc::DHP, base_hook_item, traits_BasketQueue_disposer > BasketQueue_DHP_base;
+
+ // DHP member hook
+ struct traits_BasketQueue_member : public traits_BasketQueue_disposer
+ {
+ typedef ci::basket_queue::member_hook< offsetof( member_hook_item, hMember ), ci::opt::gc < cds::gc::DHP > > hook;
+ };
+ typedef ci::BasketQueue< cds::gc::DHP, member_hook_item, traits_BasketQueue_member >BasketQueue_DHP_member;
+
+ /// DHP base hook + item counter
+ typedef ci::BasketQueue< cds::gc::DHP, base_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ ,ci::opt::hook<
+ ci::basket_queue::base_hook< ci::opt::gc<cds::gc::DHP> >
+ >
+ ,co::item_counter< cds::atomicity::item_counter >
+ ,co::memory_model< co::v::relaxed_ordering >
+ >::type
+ > BasketQueue_DHP_base_ic;
+
+ // DHP member hook + item counter
+ typedef ci::BasketQueue< cds::gc::DHP, member_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::hook<
+ ci::basket_queue::member_hook<
+ offsetof(basket_queue::member_hook_item<cds::gc::DHP>, hMember),
+ ci::opt::gc<cds::gc::DHP>
+ >
+ >
+ ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ ,co::item_counter< cds::atomicity::item_counter >
+ >::type
+ > BasketQueue_DHP_member_ic;
+
+ // DHP base hook + stat
+ typedef ci::BasketQueue< cds::gc::DHP, base_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::hook<
+ ci::basket_queue::base_hook< ci::opt::gc<cds::gc::DHP> >
+ >
+ ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ ,co::stat< ci::basket_queue::stat<> >
+ >::type
+ > BasketQueue_DHP_base_stat;
+
+ // DHP member hook + stat
+ typedef ci::BasketQueue< cds::gc::DHP, member_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::hook<
+ ci::basket_queue::member_hook<
+ offsetof(basket_queue::member_hook_item<cds::gc::DHP>, hMember),
+ ci::opt::gc<cds::gc::DHP>
+ >
+ >
+ ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ ,co::stat< ci::basket_queue::stat<> >
+ >::type
+ > BasketQueue_DHP_member_stat;
+
+ // DHP base hook + alignment
+ typedef ci::BasketQueue< cds::gc::DHP, base_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ ,ci::opt::hook<
+ ci::basket_queue::base_hook< ci::opt::gc<cds::gc::DHP> >
+ >
+ ,co::alignment< 32 >
+ >::type
+ > BasketQueue_DHP_base_align;
+
+ // DHP member hook + alignment
+ typedef ci::BasketQueue< cds::gc::DHP, member_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::hook<
+ ci::basket_queue::member_hook<
+ offsetof(basket_queue::member_hook_item<cds::gc::DHP>, hMember),
+ ci::opt::gc<cds::gc::DHP>
+ >
+ >
+ ,co::alignment< 32 >
+ ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ >::type
+ > BasketQueue_DHP_member_align;
+
+ // DHP base hook + no alignment
+ typedef ci::BasketQueue< cds::gc::DHP, base_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::hook<
+ ci::basket_queue::base_hook< ci::opt::gc<cds::gc::DHP> >
+ >
+ ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ ,co::alignment< co::no_special_alignment >
+ >::type
+ > BasketQueue_DHP_base_noalign;
+
+ // DHP member hook + no alignment
+ typedef ci::BasketQueue< cds::gc::DHP, member_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ ,ci::opt::hook<
+ ci::basket_queue::member_hook<
+ offsetof(basket_queue::member_hook_item<cds::gc::DHP>, hMember),
+ ci::opt::gc<cds::gc::DHP>
+ >
+ >
+ ,co::alignment< co::no_special_alignment >
+ >::type
+ > BasketQueue_DHP_member_noalign;
+
+
+ // DHP base hook + cache alignment
+ typedef ci::BasketQueue< cds::gc::DHP, base_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::hook<
+ ci::basket_queue::base_hook< ci::opt::gc<cds::gc::DHP> >
+ >
+ ,co::alignment< co::cache_line_alignment >
+ ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ >::type
+ > BasketQueue_DHP_base_cachealign;
+
+ // DHP member hook + cache alignment
+ typedef ci::BasketQueue< cds::gc::DHP, member_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::hook<
+ ci::basket_queue::member_hook<
+ offsetof(basket_queue::member_hook_item<cds::gc::DHP>, hMember),
+ ci::opt::gc<cds::gc::DHP>
+ >
+ >
+ ,co::alignment< co::cache_line_alignment >
+ ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ >::type
+ > BasketQueue_DHP_member_cachealign;
+ } // namespace
+
+ TEST(BasketQueue_DHP_base)
+ TEST(BasketQueue_DHP_member)
+ TEST(BasketQueue_DHP_base_ic)
+ TEST(BasketQueue_DHP_member_ic)
+ TEST(BasketQueue_DHP_base_stat)
+ TEST(BasketQueue_DHP_member_stat)
+ TEST(BasketQueue_DHP_base_align)
+ TEST(BasketQueue_DHP_member_align)
+ TEST(BasketQueue_DHP_base_noalign)
+ TEST(BasketQueue_DHP_member_noalign)
+ TEST(BasketQueue_DHP_base_cachealign)
+ TEST(BasketQueue_DHP_member_cachealign)
+}
//$$CDS-header$$
#include "hdr_intrusive_msqueue.h"
-
-#include "hdr_intrusive_basketqueue_node.h"
#include <cds/gc/hp.h>
+#include <cds/intrusive/basket_queue.h>
namespace queue {
#define TEST(X) void IntrusiveQueueHeaderTest::test_##X() { test_basket<X>(); }
namespace {
- typedef ci::BasketQueue< cds::gc::HP,
- basket_queue::base_hook_item<cds::gc::HP>
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- > BasketQueue_HP_default;
+ typedef IntrusiveQueueHeaderTest::base_hook_item< ci::basket_queue::node<cds::gc::HP> > base_hook_item;
+ typedef IntrusiveQueueHeaderTest::member_hook_item< ci::basket_queue::node<cds::gc::HP> > member_hook_item;
+
+ struct traits_BasketQueue_HP_default : public ci::basket_queue::traits
+ {
+ typedef IntrusiveQueueHeaderTest::faked_disposer disposer;
+ };
+ typedef ci::BasketQueue< cds::gc::HP, base_hook_item, traits_BasketQueue_HP_default > BasketQueue_HP_default;
/// HP + item counter
- typedef ci::BasketQueue< cds::gc::HP,
- basket_queue::base_hook_item<cds::gc::HP>
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,co::item_counter< cds::atomicity::item_counter >
- ,co::memory_model< co::v::sequential_consistent >
- > BasketQueue_HP_default_ic;
+ struct traits_BasketQueue_HP_default_ic : public traits_BasketQueue_HP_default
+ {
+ typedef cds::atomicity::item_counter item_counter;
+ typedef co::v::sequential_consistent memory_model;
+ };
+ typedef ci::BasketQueue< cds::gc::HP, base_hook_item, traits_BasketQueue_HP_default_ic > BasketQueue_HP_default_ic;
/// HP + stat
- typedef ci::BasketQueue< cds::gc::HP,
- basket_queue::base_hook_item<cds::gc::HP>
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,co::stat< ci::queue_stat<> >
+ typedef ci::BasketQueue< cds::gc::HP, base_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ ,co::stat< ci::basket_queue::stat<> >
+ >::type
> BasketQueue_HP_default_stat;
// HP base hook
- typedef ci::BasketQueue< cds::gc::HP,
- basket_queue::base_hook_item<cds::gc::HP>
- ,ci::opt::hook<
- ci::basket_queue::base_hook< ci::opt::gc<cds::gc::HP> >
- >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- > BasketQueue_HP_base;
+ struct traits_BasketQueue_HP_base : public ci::basket_queue::traits
+ {
+ typedef IntrusiveQueueHeaderTest::faked_disposer disposer;
+ typedef ci::basket_queue::base_hook< ci::opt::gc<cds::gc::HP> > hook;
+ };
+ typedef ci::BasketQueue< cds::gc::HP, base_hook_item, traits_BasketQueue_HP_base > BasketQueue_HP_base;
// HP member hook
- typedef ci::BasketQueue< cds::gc::HP,
- basket_queue::member_hook_item<cds::gc::HP>
- ,ci::opt::hook<
- ci::basket_queue::member_hook<
- offsetof(basket_queue::member_hook_item<cds::gc::HP>, hMember),
- ci::opt::gc<cds::gc::HP>
- >
- >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- > BasketQueue_HP_member;
+ struct traits_BasketQueue_HP_member : public traits_BasketQueue_HP_base
+ {
+ typedef ci::basket_queue::member_hook <
+ offsetof( member_hook_item, hMember ),
+ ci::opt::gc < cds::gc::HP >
+ > hook;
+
+ };
+ typedef ci::BasketQueue< cds::gc::HP, member_hook_item, traits_BasketQueue_HP_member > BasketQueue_HP_member;
/// HP base hook + item counter
- typedef ci::BasketQueue< cds::gc::HP,
- basket_queue::base_hook_item<cds::gc::HP>
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,ci::opt::hook<
- ci::basket_queue::base_hook< ci::opt::gc<cds::gc::HP> >
- >
- ,co::item_counter< cds::atomicity::item_counter >
- ,co::memory_model< co::v::relaxed_ordering >
+ typedef ci::BasketQueue< cds::gc::HP, base_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ ,ci::opt::hook<
+ ci::basket_queue::base_hook< ci::opt::gc<cds::gc::HP> >
+ >
+ ,co::item_counter< cds::atomicity::item_counter >
+ ,co::memory_model< co::v::relaxed_ordering >
+ >::type
> BasketQueue_HP_base_ic;
// HP member hook + item counter
- typedef ci::BasketQueue< cds::gc::HP,
- basket_queue::member_hook_item<cds::gc::HP>
- ,ci::opt::hook<
- ci::basket_queue::member_hook<
- offsetof(basket_queue::member_hook_item<cds::gc::HP>, hMember),
- ci::opt::gc<cds::gc::HP>
+ typedef ci::BasketQueue< cds::gc::HP, member_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::hook<
+ ci::basket_queue::member_hook<
+ offsetof(basket_queue::member_hook_item<cds::gc::HP>, hMember),
+ ci::opt::gc<cds::gc::HP>
+ >
>
- >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,co::item_counter< cds::atomicity::item_counter >
+ ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ ,co::item_counter< cds::atomicity::item_counter >
+ >::type
> BasketQueue_HP_member_ic;
// HP base hook + stat
- typedef ci::BasketQueue< cds::gc::HP,
- basket_queue::base_hook_item<cds::gc::HP>
- ,ci::opt::hook<
- ci::basket_queue::base_hook< ci::opt::gc<cds::gc::HP> >
- >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,co::stat< ci::queue_stat<> >
+ typedef ci::BasketQueue< cds::gc::HP, base_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::hook<
+ ci::basket_queue::base_hook< ci::opt::gc<cds::gc::HP> >
+ >
+ ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ ,co::stat< ci::basket_queue::stat<> >
+ >::type
> BasketQueue_HP_base_stat;
// HP member hook + stat
- typedef ci::BasketQueue< cds::gc::HP,
- basket_queue::member_hook_item<cds::gc::HP>
- ,ci::opt::hook<
- ci::basket_queue::member_hook<
- offsetof(basket_queue::member_hook_item<cds::gc::HP>, hMember),
- ci::opt::gc<cds::gc::HP>
+ typedef ci::BasketQueue< cds::gc::HP, member_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::hook<
+ ci::basket_queue::member_hook<
+ offsetof(member_hook_item, hMember),
+ ci::opt::gc<cds::gc::HP>
+ >
>
- >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,co::stat< ci::queue_stat<> >
+ ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ ,co::stat< ci::basket_queue::stat<> >
+ >::type
> BasketQueue_HP_member_stat;
// HP base hook + alignment
- typedef ci::BasketQueue< cds::gc::HP,
- basket_queue::base_hook_item<cds::gc::HP>
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,ci::opt::hook<
- ci::basket_queue::base_hook< ci::opt::gc<cds::gc::HP> >
- >
- ,co::alignment< 32 >
+ typedef ci::BasketQueue< cds::gc::HP, base_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ ,ci::opt::hook<
+ ci::basket_queue::base_hook< ci::opt::gc<cds::gc::HP> >
+ >
+ ,co::alignment< 32 >
+ >::type
> BasketQueue_HP_base_align;
// HP member hook + alignment
- typedef ci::BasketQueue< cds::gc::HP,
- basket_queue::member_hook_item<cds::gc::HP>
- ,ci::opt::hook<
- ci::basket_queue::member_hook<
- offsetof(basket_queue::member_hook_item<cds::gc::HP>, hMember),
- ci::opt::gc<cds::gc::HP>
+ typedef ci::BasketQueue< cds::gc::HP, member_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::hook<
+ ci::basket_queue::member_hook<
+ offsetof(member_hook_item, hMember),
+ ci::opt::gc<cds::gc::HP>
+ >
>
- >
- ,co::alignment< 32 >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ ,co::alignment< 32 >
+ ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ >::type
> BasketQueue_HP_member_align;
// HP base hook + no alignment
- typedef ci::BasketQueue< cds::gc::HP,
- basket_queue::base_hook_item<cds::gc::HP>
- ,ci::opt::hook<
- ci::basket_queue::base_hook< ci::opt::gc<cds::gc::HP> >
- >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,co::alignment< co::no_special_alignment >
+ typedef ci::BasketQueue< cds::gc::HP, base_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::hook<
+ ci::basket_queue::base_hook< ci::opt::gc<cds::gc::HP> >
+ >
+ ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ ,co::alignment< co::no_special_alignment >
+ >::type
> BasketQueue_HP_base_noalign;
// HP member hook + no alignment
- typedef ci::BasketQueue< cds::gc::HP,
- basket_queue::member_hook_item<cds::gc::HP>
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,ci::opt::hook<
- ci::basket_queue::member_hook<
- offsetof(basket_queue::member_hook_item<cds::gc::HP>, hMember),
- ci::opt::gc<cds::gc::HP>
+ typedef ci::BasketQueue< cds::gc::HP, member_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ ,ci::opt::hook<
+ ci::basket_queue::member_hook<
+ offsetof(member_hook_item, hMember),
+ ci::opt::gc<cds::gc::HP>
+ >
>
- >
- ,co::alignment< co::no_special_alignment >
+ ,co::alignment< co::no_special_alignment >
+ >::type
> BasketQueue_HP_member_noalign;
// HP base hook + cache alignment
- typedef ci::BasketQueue< cds::gc::HP,
- basket_queue::base_hook_item<cds::gc::HP>
- ,ci::opt::hook<
- ci::basket_queue::base_hook< ci::opt::gc<cds::gc::HP> >
- >
- ,co::alignment< co::cache_line_alignment >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ typedef ci::BasketQueue< cds::gc::HP, base_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::hook<
+ ci::basket_queue::base_hook< ci::opt::gc<cds::gc::HP> >
+ >
+ ,co::alignment< co::cache_line_alignment >
+ ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
+ >::type
> BasketQueue_HP_base_cachealign;
// HP member hook + cache alignment
- typedef ci::BasketQueue< cds::gc::HP,
- basket_queue::member_hook_item<cds::gc::HP>
- ,ci::opt::hook<
- ci::basket_queue::member_hook<
- offsetof(basket_queue::member_hook_item<cds::gc::HP>, hMember),
- ci::opt::gc<cds::gc::HP>
+ typedef ci::BasketQueue< cds::gc::HP, member_hook_item,
+ typename ci::basket_queue::make_traits<
+ ci::opt::hook<
+ ci::basket_queue::member_hook<
+ offsetof(member_hook_item, hMember),
+ ci::opt::gc<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
> BasketQueue_HP_member_cachealign;
-
- }
+ } // namespace
TEST(BasketQueue_HP_default)
TEST(BasketQueue_HP_default_ic)
+++ /dev/null
-//$$CDS-header$$
-
-#include "hdr_intrusive_msqueue.h"
-
-#include "hdr_intrusive_basketqueue_node.h"
-#include <cds/gc/hrc.h>
-
-namespace queue {
-
-#define TEST(X) void IntrusiveQueueHeaderTest::test_##X() { test_basket<X>(); }
-
- namespace {
- // HRC base hook
- typedef ci::BasketQueue< cds::gc::HRC,
- basket_queue::base_hook_item<cds::gc::HRC>
- ,ci::opt::hook<
- ci::basket_queue::base_hook< ci::opt::gc<cds::gc::HRC> >
- >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- > BasketQueue_HRC_base;
-
- /// HRC base hook + item counter
- typedef ci::BasketQueue< cds::gc::HRC,
- basket_queue::base_hook_item<cds::gc::HRC>
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,ci::opt::hook<
- ci::basket_queue::base_hook< ci::opt::gc<cds::gc::HRC> >
- >
- ,co::item_counter< cds::atomicity::item_counter >
- ,co::memory_model< co::v::relaxed_ordering >
- > BasketQueue_HRC_base_ic;
-
- // HRC base hook + stat
- typedef ci::BasketQueue< cds::gc::HRC,
- basket_queue::base_hook_item<cds::gc::HRC>
- ,ci::opt::hook<
- ci::basket_queue::base_hook< ci::opt::gc<cds::gc::HRC> >
- >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,co::stat< ci::queue_stat<> >
- > BasketQueue_HRC_base_stat;
-
- // HRC base hook + alignment
- typedef ci::BasketQueue< cds::gc::HRC,
- basket_queue::base_hook_item<cds::gc::HRC>
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,ci::opt::hook<
- ci::basket_queue::base_hook< ci::opt::gc<cds::gc::HRC> >
- >
- ,co::alignment< 32 >
- > BasketQueue_HRC_base_align;
-
- }
-
- TEST(BasketQueue_HRC_base)
- TEST(BasketQueue_HRC_base_ic)
- TEST(BasketQueue_HRC_base_stat)
- TEST(BasketQueue_HRC_base_align)
-}
+++ /dev/null
-//$$CDS-header$$
-
-#ifndef CDSTEST_HDR_TEST_INTRUSIVE_BASKET_QUEUE_NODE_H
-#define CDSTEST_HDR_TEST_INTRUSIVE_BASKET_QUEUE_NODE_H
-
-#include <cds/intrusive/basket_queue.h>
-
-namespace queue {
- namespace ci = cds::intrusive;
- namespace co = cds::opt;
-
- namespace basket_queue {
- template <typename GC>
- struct base_hook_item: public ci::basket_queue::node< GC >
- {
- int nVal;
- int nDisposeCount;
-
- base_hook_item()
- : nDisposeCount(0)
- {}
- };
-
- template <typename GC>
- struct member_hook_item
- {
- int nVal;
- int nDisposeCount;
- ci::basket_queue::node< GC > hMember;
-
- member_hook_item()
- : nDisposeCount(0)
- {}
- };
-
- } // namespace basket_queue
-} // queue
-
-#endif // #ifndef CDSTEST_HDR_TEST_INTRUSIVE_BASKET_QUEUE_NODE_H
+++ /dev/null
-//$$CDS-header$$
-
-#include "hdr_intrusive_msqueue.h"
-
-#include "hdr_intrusive_basketqueue_node.h"
-#include <cds/gc/ptb.h>
-
-namespace queue {
-
-#define TEST(X) void IntrusiveQueueHeaderTest::test_##X() { test_basket<X>(); }
-
- namespace {
- // PTB base hook
- typedef ci::BasketQueue< cds::gc::PTB,
- basket_queue::base_hook_item<cds::gc::PTB>
- ,ci::opt::hook<
- ci::basket_queue::base_hook< ci::opt::gc<cds::gc::PTB> >
- >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- > BasketQueue_PTB_base;
-
- // PTB member hook
- typedef ci::BasketQueue< cds::gc::PTB,
- basket_queue::member_hook_item<cds::gc::PTB>
- ,ci::opt::hook<
- ci::basket_queue::member_hook<
- offsetof(basket_queue::member_hook_item<cds::gc::PTB>, hMember),
- ci::opt::gc<cds::gc::PTB>
- >
- >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- > BasketQueue_PTB_member;
-
- /// PTB base hook + item counter
- typedef ci::BasketQueue< cds::gc::PTB,
- basket_queue::base_hook_item<cds::gc::PTB>
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,ci::opt::hook<
- ci::basket_queue::base_hook< ci::opt::gc<cds::gc::PTB> >
- >
- ,co::item_counter< cds::atomicity::item_counter >
- ,co::memory_model< co::v::relaxed_ordering >
- > BasketQueue_PTB_base_ic;
-
- // PTB member hook + item counter
- typedef ci::BasketQueue< cds::gc::PTB,
- basket_queue::member_hook_item<cds::gc::PTB>
- ,ci::opt::hook<
- ci::basket_queue::member_hook<
- offsetof(basket_queue::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 >
- > BasketQueue_PTB_member_ic;
-
- // PTB base hook + stat
- typedef ci::BasketQueue< cds::gc::PTB,
- basket_queue::base_hook_item<cds::gc::PTB>
- ,ci::opt::hook<
- ci::basket_queue::base_hook< ci::opt::gc<cds::gc::PTB> >
- >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,co::stat< ci::queue_stat<> >
- > BasketQueue_PTB_base_stat;
-
- // PTB member hook + stat
- typedef ci::BasketQueue< cds::gc::PTB,
- basket_queue::member_hook_item<cds::gc::PTB>
- ,ci::opt::hook<
- ci::basket_queue::member_hook<
- offsetof(basket_queue::member_hook_item<cds::gc::PTB>, hMember),
- ci::opt::gc<cds::gc::PTB>
- >
- >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,co::stat< ci::queue_stat<> >
- > BasketQueue_PTB_member_stat;
-
- // PTB base hook + alignment
- typedef ci::BasketQueue< cds::gc::PTB,
- basket_queue::base_hook_item<cds::gc::PTB>
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,ci::opt::hook<
- ci::basket_queue::base_hook< ci::opt::gc<cds::gc::PTB> >
- >
- ,co::alignment< 32 >
- > BasketQueue_PTB_base_align;
-
- // PTB member hook + alignment
- typedef ci::BasketQueue< cds::gc::PTB,
- basket_queue::member_hook_item<cds::gc::PTB>
- ,ci::opt::hook<
- ci::basket_queue::member_hook<
- offsetof(basket_queue::member_hook_item<cds::gc::PTB>, hMember),
- ci::opt::gc<cds::gc::PTB>
- >
- >
- ,co::alignment< 32 >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- > BasketQueue_PTB_member_align;
-
- // PTB base hook + no alignment
- typedef ci::BasketQueue< cds::gc::PTB,
- basket_queue::base_hook_item<cds::gc::PTB>
- ,ci::opt::hook<
- ci::basket_queue::base_hook< ci::opt::gc<cds::gc::PTB> >
- >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,co::alignment< co::no_special_alignment >
- > BasketQueue_PTB_base_noalign;
-
- // PTB member hook + no alignment
- typedef ci::BasketQueue< cds::gc::PTB,
- basket_queue::member_hook_item<cds::gc::PTB>
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- ,ci::opt::hook<
- ci::basket_queue::member_hook<
- offsetof(basket_queue::member_hook_item<cds::gc::PTB>, hMember),
- ci::opt::gc<cds::gc::PTB>
- >
- >
- ,co::alignment< co::no_special_alignment >
- > BasketQueue_PTB_member_noalign;
-
-
- // PTB base hook + cache alignment
- typedef ci::BasketQueue< cds::gc::PTB,
- basket_queue::base_hook_item<cds::gc::PTB>
- ,ci::opt::hook<
- ci::basket_queue::base_hook< ci::opt::gc<cds::gc::PTB> >
- >
- ,co::alignment< co::cache_line_alignment >
- ,ci::opt::disposer< IntrusiveQueueHeaderTest::faked_disposer >
- > BasketQueue_PTB_base_cachealign;
-
- // PTB member hook + cache alignment
- typedef ci::BasketQueue< cds::gc::PTB,
- basket_queue::member_hook_item<cds::gc::PTB>
- ,ci::opt::hook<
- ci::basket_queue::member_hook<
- offsetof(basket_queue::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 >
- > BasketQueue_PTB_member_cachealign;
-
- }
-
- TEST(BasketQueue_PTB_base)
- TEST(BasketQueue_PTB_member)
- TEST(BasketQueue_PTB_base_ic)
- TEST(BasketQueue_PTB_member_ic)
- TEST(BasketQueue_PTB_base_stat)
- TEST(BasketQueue_PTB_member_stat)
- TEST(BasketQueue_PTB_base_align)
- TEST(BasketQueue_PTB_member_align)
- TEST(BasketQueue_PTB_base_noalign)
- TEST(BasketQueue_PTB_member_noalign)
- TEST(BasketQueue_PTB_base_cachealign)
- TEST(BasketQueue_PTB_member_cachealign)
-}
void test_BasketQueue_HP_member_noalign();
void test_BasketQueue_HP_base_cachealign();
void test_BasketQueue_HP_member_cachealign();
- void test_BasketQueue_HRC_base();
- void test_BasketQueue_HRC_base_ic();
- void test_BasketQueue_HRC_base_stat();
- void test_BasketQueue_HRC_base_align();
- void test_BasketQueue_PTB_base();
- void test_BasketQueue_PTB_member();
- void test_BasketQueue_PTB_base_ic();
- void test_BasketQueue_PTB_member_ic();
- void test_BasketQueue_PTB_base_stat();
- void test_BasketQueue_PTB_member_stat();
- void test_BasketQueue_PTB_base_align();
- void test_BasketQueue_PTB_member_align();
- void test_BasketQueue_PTB_base_noalign();
- void test_BasketQueue_PTB_member_noalign();
- void test_BasketQueue_PTB_base_cachealign();
- void test_BasketQueue_PTB_member_cachealign();
+ void test_BasketQueue_DHP_base();
+ void test_BasketQueue_DHP_member();
+ void test_BasketQueue_DHP_base_ic();
+ void test_BasketQueue_DHP_member_ic();
+ void test_BasketQueue_DHP_base_stat();
+ void test_BasketQueue_DHP_member_stat();
+ void test_BasketQueue_DHP_base_align();
+ void test_BasketQueue_DHP_member_align();
+ void test_BasketQueue_DHP_base_noalign();
+ void test_BasketQueue_DHP_member_noalign();
+ void test_BasketQueue_DHP_base_cachealign();
+ void test_BasketQueue_DHP_member_cachealign();
void test_TsigasCycleQueue_stat();
void test_TsigasCycleQueue_stat_ic();
CPPUNIT_TEST(test_BasketQueue_HP_member_noalign)
CPPUNIT_TEST(test_BasketQueue_HP_base_cachealign)
CPPUNIT_TEST(test_BasketQueue_HP_member_cachealign)
- CPPUNIT_TEST(test_BasketQueue_HRC_base)
- CPPUNIT_TEST(test_BasketQueue_HRC_base_ic)
- CPPUNIT_TEST(test_BasketQueue_HRC_base_stat)
- CPPUNIT_TEST(test_BasketQueue_HRC_base_align)
- CPPUNIT_TEST(test_BasketQueue_PTB_base)
- CPPUNIT_TEST(test_BasketQueue_PTB_member)
- CPPUNIT_TEST(test_BasketQueue_PTB_base_ic)
- CPPUNIT_TEST(test_BasketQueue_PTB_member_ic)
- CPPUNIT_TEST(test_BasketQueue_PTB_base_stat)
- CPPUNIT_TEST(test_BasketQueue_PTB_member_stat)
- CPPUNIT_TEST(test_BasketQueue_PTB_base_align)
- CPPUNIT_TEST(test_BasketQueue_PTB_member_align)
- CPPUNIT_TEST(test_BasketQueue_PTB_base_noalign)
- CPPUNIT_TEST(test_BasketQueue_PTB_member_noalign)
- CPPUNIT_TEST(test_BasketQueue_PTB_base_cachealign)
- CPPUNIT_TEST(test_BasketQueue_PTB_member_cachealign)
+ CPPUNIT_TEST(test_BasketQueue_DHP_base)
+ CPPUNIT_TEST(test_BasketQueue_DHP_member)
+ CPPUNIT_TEST(test_BasketQueue_DHP_base_ic)
+ CPPUNIT_TEST(test_BasketQueue_DHP_member_ic)
+ CPPUNIT_TEST(test_BasketQueue_DHP_base_stat)
+ CPPUNIT_TEST(test_BasketQueue_DHP_member_stat)
+ CPPUNIT_TEST(test_BasketQueue_DHP_base_align)
+ CPPUNIT_TEST(test_BasketQueue_DHP_member_align)
+ CPPUNIT_TEST(test_BasketQueue_DHP_base_noalign)
+ CPPUNIT_TEST(test_BasketQueue_DHP_member_noalign)
+ CPPUNIT_TEST(test_BasketQueue_DHP_base_cachealign)
+ CPPUNIT_TEST(test_BasketQueue_DHP_member_cachealign)
CPPUNIT_TEST(test_TsigasCycleQueue_stat)
CPPUNIT_TEST(test_TsigasCycleQueue_stat_ic)
void OptimisticQueue_PTB_Counted_relax_align();
void OptimisticQueue_PTB_Counted_seqcst_align();
- void BasketQueue_HP();
- void BasketQueue_HP_relax();
- void BasketQueue_HP_seqcst();
- void BasketQueue_HP_relax_align();
- void BasketQueue_HP_seqcst_align();
- void BasketQueue_HP_Counted();
- void BasketQueue_HP_Counted_relax();
- void BasketQueue_HP_Counted_seqcst();
- void BasketQueue_HP_Counted_relax_align();
- void BasketQueue_HP_Counted_seqcst_align();
-
- void BasketQueue_HRC();
- void BasketQueue_HRC_relax();
- void BasketQueue_HRC_seqcst();
- void BasketQueue_HRC_relax_align();
- void BasketQueue_HRC_seqcst_align();
- void BasketQueue_HRC_Counted();
- void BasketQueue_HRC_Counted_relax();
- void BasketQueue_HRC_Counted_seqcst();
- void BasketQueue_HRC_Counted_relax_align();
- void BasketQueue_HRC_Counted_seqcst_align();
-
- void BasketQueue_PTB();
- void BasketQueue_PTB_relax();
- void BasketQueue_PTB_seqcst();
- void BasketQueue_PTB_relax_align();
- void BasketQueue_PTB_seqcst_align();
- void BasketQueue_PTB_Counted();
- void BasketQueue_PTB_Counted_relax();
- void BasketQueue_PTB_Counted_seqcst();
- void BasketQueue_PTB_Counted_relax_align();
- void BasketQueue_PTB_Counted_seqcst_align();
-
void FCQueue_deque();
void FCQueue_deque_elimination();
void FCQueue_deque_mutex();
CPPUNIT_TEST(OptimisticQueue_PTB_Counted_relax_align);
CPPUNIT_TEST(OptimisticQueue_PTB_Counted_seqcst_align);
- CPPUNIT_TEST(BasketQueue_HP);
- CPPUNIT_TEST(BasketQueue_HP_relax);
- CPPUNIT_TEST(BasketQueue_HP_seqcst);
- CPPUNIT_TEST(BasketQueue_HP_relax_align);
- CPPUNIT_TEST(BasketQueue_HP_seqcst_align);
- CPPUNIT_TEST(BasketQueue_HP_Counted);
- CPPUNIT_TEST(BasketQueue_HP_Counted_relax);
- CPPUNIT_TEST(BasketQueue_HP_Counted_seqcst);
- CPPUNIT_TEST(BasketQueue_HP_Counted_relax_align);
- CPPUNIT_TEST(BasketQueue_HP_Counted_seqcst_align);
-
- CPPUNIT_TEST(BasketQueue_HRC);
- CPPUNIT_TEST(BasketQueue_HRC_relax);
- CPPUNIT_TEST(BasketQueue_HRC_seqcst);
- CPPUNIT_TEST(BasketQueue_HRC_relax_align);
- CPPUNIT_TEST(BasketQueue_HRC_seqcst_align);
- CPPUNIT_TEST(BasketQueue_HRC_Counted);
- CPPUNIT_TEST(BasketQueue_HRC_Counted_relax);
- CPPUNIT_TEST(BasketQueue_HRC_Counted_seqcst);
- CPPUNIT_TEST(BasketQueue_HRC_Counted_relax_align);
- CPPUNIT_TEST(BasketQueue_HRC_Counted_seqcst_align);
-
- CPPUNIT_TEST(BasketQueue_PTB);
- CPPUNIT_TEST(BasketQueue_PTB_relax);
- CPPUNIT_TEST(BasketQueue_PTB_seqcst);
- CPPUNIT_TEST(BasketQueue_PTB_relax_align);
- CPPUNIT_TEST(BasketQueue_PTB_seqcst_align);
- CPPUNIT_TEST(BasketQueue_PTB_Counted);
- CPPUNIT_TEST(BasketQueue_PTB_Counted_relax);
- CPPUNIT_TEST(BasketQueue_PTB_Counted_seqcst);
- CPPUNIT_TEST(BasketQueue_PTB_Counted_relax_align);
- CPPUNIT_TEST(BasketQueue_PTB_Counted_seqcst_align);
-
CPPUNIT_TEST(FCQueue_deque)
CPPUNIT_TEST(FCQueue_deque_elimination)
CPPUNIT_TEST(FCQueue_deque_mutex)
void OptimisticQueue_DHP_Counted_seqcst();
void OptimisticQueue_DHP_Counted_relax_align();
void OptimisticQueue_DHP_Counted_seqcst_align();
-
+*/
void BasketQueue_HP();
void BasketQueue_HP_relax();
void BasketQueue_HP_seqcst();
void BasketQueue_DHP_Counted_seqcst();
void BasketQueue_DHP_Counted_relax_align();
void BasketQueue_DHP_Counted_seqcst_align();
-
+/*
void FCQueue_deque();
void FCQueue_deque_elimination();
void FCQueue_deque_mutex();
CPPUNIT_TEST(OptimisticQueue_DHP_Counted_seqcst);
CPPUNIT_TEST(OptimisticQueue_DHP_Counted_relax_align);
CPPUNIT_TEST(OptimisticQueue_DHP_Counted_seqcst_align);
-
+*/
CPPUNIT_TEST(BasketQueue_HP);
CPPUNIT_TEST(BasketQueue_HP_relax);
CPPUNIT_TEST(BasketQueue_HP_seqcst);
CPPUNIT_TEST(BasketQueue_DHP_Counted_seqcst);
CPPUNIT_TEST(BasketQueue_DHP_Counted_relax_align);
CPPUNIT_TEST(BasketQueue_DHP_Counted_seqcst_align);
-
+/*
CPPUNIT_TEST(FCQueue_deque)
CPPUNIT_TEST(FCQueue_deque_elimination)
CPPUNIT_TEST(FCQueue_deque_mutex)
TEST_CASE(BasketQueue_HP_ic, cds::intrusive::basket_queue::node< cds::gc::HP > ) \
TEST_CASE(BasketQueue_HP_stat, cds::intrusive::basket_queue::node< cds::gc::HP > ) \
TEST_CASE(BasketQueue_HP_seqcst, cds::intrusive::basket_queue::node< cds::gc::HP > ) \
- TEST_CASE(BasketQueue_HRC, cds::intrusive::basket_queue::node< cds::gc::HRC > ) \
- TEST_CASE(BasketQueue_HRC_ic, cds::intrusive::basket_queue::node< cds::gc::HRC > ) \
- TEST_CASE(BasketQueue_HRC_stat, cds::intrusive::basket_queue::node< cds::gc::HRC > ) \
- TEST_CASE(BasketQueue_HRC_seqcst, cds::intrusive::basket_queue::node< cds::gc::HRC > ) \
- TEST_CASE(BasketQueue_PTB, cds::intrusive::basket_queue::node< cds::gc::PTB > ) \
- TEST_CASE(BasketQueue_PTB_ic, cds::intrusive::basket_queue::node< cds::gc::PTB > ) \
- TEST_CASE(BasketQueue_PTB_stat, cds::intrusive::basket_queue::node< cds::gc::PTB > ) \
- TEST_CASE(BasketQueue_PTB_seqcst, cds::intrusive::basket_queue::node< cds::gc::PTB > )
+ TEST_CASE(BasketQueue_DHP, cds::intrusive::basket_queue::node< cds::gc::DHP > ) \
+ TEST_CASE(BasketQueue_DHP_ic, cds::intrusive::basket_queue::node< cds::gc::DHP > ) \
+ TEST_CASE(BasketQueue_DHP_stat, cds::intrusive::basket_queue::node< cds::gc::DHP > ) \
+ TEST_CASE(BasketQueue_DHP_seqcst, cds::intrusive::basket_queue::node< cds::gc::DHP > )
#define CDSUNIT_TEST_BasketQueue \
CPPUNIT_TEST(BasketQueue_HP) \
CPPUNIT_TEST(BasketQueue_HP_ic) \
CPPUNIT_TEST(BasketQueue_HP_stat) \
CPPUNIT_TEST(BasketQueue_HP_seqcst) \
- /*CPPUNIT_TEST(BasketQueue_HRC)*/ \
- /*CPPUNIT_TEST(BasketQueue_HRC_ic)*/ \
- /*CPPUNIT_TEST(BasketQueue_HRC_stat)*/ \
- /*CPPUNIT_TEST(BasketQueue_HRC_seqcst)*/ \
- CPPUNIT_TEST(BasketQueue_PTB) \
- CPPUNIT_TEST(BasketQueue_PTB_ic) \
- CPPUNIT_TEST(BasketQueue_PTB_stat) \
- CPPUNIT_TEST(BasketQueue_PTB_seqcst)
+ CPPUNIT_TEST(BasketQueue_DHP) \
+ CPPUNIT_TEST(BasketQueue_DHP_ic) \
+ CPPUNIT_TEST(BasketQueue_DHP_stat) \
+ CPPUNIT_TEST(BasketQueue_DHP_seqcst)
// TsigasCycleQueue
#define CDSUNIT_DECLARE_TsigasCycleQueue \
};
// BasketQueue
- typedef cds::intrusive::BasketQueue< cds::gc::HP, T
- ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
- > BasketQueue_HP;
-
- typedef cds::intrusive::BasketQueue<cds::gc::HP, T
- ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
- ,cds::opt::memory_model< cds::opt::v::sequential_consistent >
- > BasketQueue_HP_seqcst;
-
- typedef cds::intrusive::BasketQueue< cds::gc::HRC, T
- ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HRC > > >
- > BasketQueue_HRC;
+ struct traits_BasketQueue_HP : public
+ cds::intrusive::basket_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
+ > ::type
+ {};
+ typedef cds::intrusive::BasketQueue< cds::gc::HP, T, traits_BasketQueue_HP > BasketQueue_HP;
- typedef cds::intrusive::BasketQueue< cds::gc::HRC, T
- ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HRC > > >
- ,cds::opt::memory_model< cds::opt::v::sequential_consistent >
- > BasketQueue_HRC_seqcst;
+ struct traits_BasketQueue_HP_seqcst: public
+ cds::intrusive::basket_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
+ , cds::opt::memory_model< cds::opt::v::sequential_consistent >
+ > ::type
+ {};
+ typedef cds::intrusive::BasketQueue<cds::gc::HP, T, traits_BasketQueue_HP_seqcst > BasketQueue_HP_seqcst;
- typedef cds::intrusive::BasketQueue< cds::gc::PTB, T
- ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::PTB > > >
- > BasketQueue_PTB;
+ struct traits_BasketQueue_DHP : public
+ cds::intrusive::basket_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::DHP > > >
+ > ::type
+ {};
+ typedef cds::intrusive::BasketQueue< cds::gc::DHP, T, traits_BasketQueue_DHP > BasketQueue_DHP;
- typedef cds::intrusive::BasketQueue< cds::gc::PTB, T
- ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::PTB > > >
- ,cds::opt::memory_model< cds::opt::v::sequential_consistent >
- > BasketQueue_PTB_seqcst;
+ struct traits_BasketQueue_DHP_seqcst: public
+ cds::intrusive::basket_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::DHP > > >
+ , cds::opt::memory_model< cds::opt::v::sequential_consistent >
+ > ::type
+ {};
+ typedef cds::intrusive::BasketQueue< cds::gc::DHP, T, traits_BasketQueue_DHP_seqcst > BasketQueue_DHP_seqcst;
// BasketQueue + item counter
- typedef cds::intrusive::BasketQueue< cds::gc::HP, T
- ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- > BasketQueue_HP_ic;
-
- typedef cds::intrusive::BasketQueue< cds::gc::HRC, T
- ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HRC > > >
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- > BasketQueue_HRC_ic;
+ struct traits_BasketQueue_HP_ic : public
+ cds::intrusive::basket_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
+ ,cds::opt::item_counter< cds::atomicity::item_counter >
+ > ::type
+ {};
+ typedef cds::intrusive::BasketQueue< cds::gc::HP, T, traits_BasketQueue_HP_ic > BasketQueue_HP_ic;
- typedef cds::intrusive::BasketQueue< cds::gc::PTB, T
- ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::PTB > > >
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- > BasketQueue_PTB_ic;
+ struct traits_BasketQueue_DHP_ic : public
+ cds::intrusive::basket_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::DHP > > >
+ ,cds::opt::item_counter< cds::atomicity::item_counter >
+ > ::type
+ {};
+ typedef cds::intrusive::BasketQueue< cds::gc::DHP, T, traits_BasketQueue_DHP_ic > BasketQueue_DHP_ic;
// BasketQueue + stat
- typedef cds::intrusive::BasketQueue< cds::gc::HP, T
- ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
- ,cds::opt::stat< cds::intrusive::queue_stat<> >
- > BasketQueue_HP_stat;
-
- typedef cds::intrusive::BasketQueue< cds::gc::HRC, T
- ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HRC > > >
- ,cds::opt::stat< cds::intrusive::queue_stat<> >
- > BasketQueue_HRC_stat;
+ struct traits_BasketQueue_HP_stat : public
+ cds::intrusive::basket_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
+ , cds::opt::stat< cds::intrusive::basket_queue::stat<> >
+ > ::type
+ {};
+ typedef cds::intrusive::BasketQueue< cds::gc::HP, T, traits_BasketQueue_HP_stat > BasketQueue_HP_stat;
- typedef cds::intrusive::BasketQueue< cds::gc::PTB, T
- ,cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::PTB > > >
- ,cds::opt::stat< cds::intrusive::queue_stat<> >
- > BasketQueue_PTB_stat;
+ struct traits_BasketQueue_DHP_stat : public
+ cds::intrusive::basket_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::DHP > > >
+ , cds::opt::stat< cds::intrusive::basket_queue::stat<> >
+ > ::type
+ {};
+ typedef cds::intrusive::BasketQueue< cds::gc::DHP, T, traits_BasketQueue_DHP_stat > BasketQueue_DHP_stat;
// FCQueue
class traits_FCQueue_delay2:
// cds::intrusive::queue_stat
template <typename Counter>
- static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::queue_stat<Counter> const& s)
+ static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::basket_queue::stat<Counter> const& s)
{
return o
<< "\tStatistics:\n"
- << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n"
- << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n"
- << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n"
- << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n"
- << "\t\tAdvance tail error: " << s.m_AdvanceTailError.get() << "\n"
- << "\t\t Bad tail: " << s.m_BadTail.get() << "\n";
+ << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n"
+ << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n"
+ << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n"
+ << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n"
+ << "\t\t Advance tail error: " << s.m_AdvanceTailError.get() << "\n"
+ << "\t\t Bad tail: " << s.m_BadTail.get() << "\n"
+ << "\t\tAdd basket attempts: " << s.m_TryAddBasket.get() << "\n"
+ << "\t\t Add basket success: " << s.m_AddBasketCount.get() << "\n";
}
- static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::queue_dummy_stat const& s)
+ static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::basket_queue::empty_stat const& s)
{
return o;
}
-
template <typename Counter>
static inline std::ostream& operator <<( std::ostream& o, cds::intrusive::msqueue::stat<Counter> const& s )
{
TEST_CASE( BasketQueue_HP_seqcst, ITEM_TYPE ) \
TEST_CASE( BasketQueue_HP_ic, ITEM_TYPE ) \
TEST_CASE( BasketQueue_HP_stat, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_HRC, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_HRC_michaelAlloc, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_HRC_seqcst, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_HRC_ic, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_HRC_stat, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_PTB, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_PTB_michaelAlloc, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_PTB_seqcst, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_PTB_ic, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_PTB_stat, ITEM_TYPE )
+ TEST_CASE( BasketQueue_DHP, ITEM_TYPE ) \
+ TEST_CASE( BasketQueue_DHP_michaelAlloc, ITEM_TYPE ) \
+ TEST_CASE( BasketQueue_DHP_seqcst, ITEM_TYPE ) \
+ TEST_CASE( BasketQueue_DHP_ic, ITEM_TYPE ) \
+ TEST_CASE( BasketQueue_DHP_stat, ITEM_TYPE )
#define CDSUNIT_TEST_BasketQueue \
CPPUNIT_TEST(BasketQueue_HP) \
CPPUNIT_TEST(BasketQueue_HP_seqcst) \
CPPUNIT_TEST(BasketQueue_HP_ic) \
CPPUNIT_TEST(BasketQueue_HP_stat) \
- CPPUNIT_TEST(BasketQueue_HRC) \
- CPPUNIT_TEST(BasketQueue_HRC_michaelAlloc) \
- CPPUNIT_TEST(BasketQueue_HRC_seqcst) \
- CPPUNIT_TEST(BasketQueue_HRC_ic) \
- CPPUNIT_TEST(BasketQueue_HRC_stat) \
- CPPUNIT_TEST(BasketQueue_PTB) \
- CPPUNIT_TEST(BasketQueue_PTB_michaelAlloc) \
- CPPUNIT_TEST(BasketQueue_PTB_seqcst) \
- CPPUNIT_TEST(BasketQueue_PTB_ic) \
- CPPUNIT_TEST(BasketQueue_PTB_stat)
+ CPPUNIT_TEST(BasketQueue_DHP) \
+ CPPUNIT_TEST(BasketQueue_DHP_michaelAlloc) \
+ CPPUNIT_TEST(BasketQueue_DHP_seqcst) \
+ CPPUNIT_TEST(BasketQueue_DHP_ic) \
+ CPPUNIT_TEST(BasketQueue_DHP_stat)
// FCQueue
};
// BasketQueue
- typedef cds::container::BasketQueue<
- cds::gc::HP , Value
- > BasketQueue_HP;
- typedef cds::container::BasketQueue<
- cds::gc::HP , Value
- ,cds::opt::allocator< memory::MichaelAllocator<int> >
- > BasketQueue_HP_michaelAlloc;
-
- typedef cds::container::BasketQueue<
- cds::gc::HP, Value
- ,cds::opt::memory_model< cds::opt::v::sequential_consistent >
- > BasketQueue_HP_seqcst;
-
- typedef cds::container::BasketQueue< cds::gc::HRC,
- Value
- > BasketQueue_HRC;
-
- typedef cds::container::BasketQueue< cds::gc::HRC,
- Value
- ,cds::opt::allocator< memory::MichaelAllocator<int> >
- > BasketQueue_HRC_michaelAlloc;
-
- typedef cds::container::BasketQueue< cds::gc::HRC,
- Value
- ,cds::opt::memory_model< cds::opt::v::sequential_consistent >
- > BasketQueue_HRC_seqcst;
+ typedef cds::container::BasketQueue< cds::gc::HP , Value > BasketQueue_HP;
+ typedef cds::container::BasketQueue< cds::gc::DHP, Value > BasketQueue_DHP;
- typedef cds::container::BasketQueue< cds::gc::PTB,
- Value
- > BasketQueue_PTB;
-
- typedef cds::container::BasketQueue< cds::gc::PTB,
- Value
- ,cds::opt::allocator< memory::MichaelAllocator<int> >
- > BasketQueue_PTB_michaelAlloc;
-
- typedef cds::container::BasketQueue< cds::gc::PTB,
- Value
- ,cds::opt::memory_model< cds::opt::v::sequential_consistent >
- > BasketQueue_PTB_seqcst;
-
- // BasketQueue + item counter
- typedef cds::container::BasketQueue< cds::gc::HP,
- Value
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- > BasketQueue_HP_ic;
-
- typedef cds::container::BasketQueue< cds::gc::HRC,
- Value
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- > BasketQueue_HRC_ic;
-
- typedef cds::container::BasketQueue< cds::gc::PTB,
- Value
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- > BasketQueue_PTB_ic;
+ struct traits_BasketQueue_michaelAlloc : public cds::container::basket_queue::traits
+ {
+ typedef memory::MichaelAllocator<int> allocator;
+ };
+ typedef cds::container::BasketQueue< cds::gc::HP, Value, traits_BasketQueue_michaelAlloc > BasketQueue_HP_michaelAlloc;
+ typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_michaelAlloc > BasketQueue_DHP_michaelAlloc;
- // BasketQueue + stat
- typedef cds::container::BasketQueue< cds::gc::HP,
- Value
- ,cds::opt::stat< cds::intrusive::queue_stat<> >
- > BasketQueue_HP_stat;
+ struct traits_BasketQueue_seqcst : public cds::container::basket_queue::traits
+ {
+ typedef cds::opt::v::sequential_consistent mamory_model;
+ };
+ typedef cds::container::BasketQueue< cds::gc::HP, Value, traits_BasketQueue_seqcst > BasketQueue_HP_seqcst;
+ typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_seqcst > BasketQueue_DHP_seqcst;
- typedef cds::container::BasketQueue< cds::gc::HRC,
- Value
- ,cds::opt::stat< cds::intrusive::queue_stat<> >
- > BasketQueue_HRC_stat;
+ struct traits_BasketQueue_ic : public cds::container::basket_queue::traits
+ {
+ typedef cds::atomicity::item_counter item_counter;
+ };
+ typedef cds::container::BasketQueue< cds::gc::HP, Value, traits_BasketQueue_ic >BasketQueue_HP_ic;
+ typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_ic >BasketQueue_DHP_ic;
- typedef cds::container::BasketQueue< cds::gc::PTB,
- Value
- ,cds::opt::stat< cds::intrusive::queue_stat<> >
- > BasketQueue_PTB_stat;
+ struct traits_BasketQueue_stat : public cds::container::basket_queue::traits
+ {
+ typedef cds::container::basket_queue::stat<> stat;
+ };
+ typedef cds::container::BasketQueue< cds::gc::HP, Value, traits_BasketQueue_stat > BasketQueue_HP_stat;
+ typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_stat > BasketQueue_DHP_stat;
// RWQueue
// cds::intrusive::queue_stat
template <typename Counter>
- static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::queue_stat<Counter> const& s)
+ static inline std::ostream& operator <<(std::ostream& o, cds::container::basket_queue::stat<Counter> const& s)
{
return o
<< "\tStatistics:\n"
- << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n"
- << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n"
- << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n"
- << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n"
- << "\t\tAdvance tail error: " << s.m_AdvanceTailError.get() << "\n"
- << "\t\t Bad tail: " << s.m_BadTail.get() << "\n";
+ << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n"
+ << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n"
+ << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n"
+ << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n"
+ << "\t\t Advance tail error: " << s.m_AdvanceTailError.get() << "\n"
+ << "\t\t Bad tail: " << s.m_BadTail.get() << "\n"
+ << "\t\tAdd basket attempts: " << s.m_TryAddBasket.get() << "\n"
+ << "\t\t Add basket success: " << s.m_AddBasketCount.get() << "\n";
}
- static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::queue_dummy_stat const& s)
+ static inline std::ostream& operator <<(std::ostream& o, cds::container::basket_queue::empty_stat const& s)
{
return o;
}