From d07c0dfb06a5be6013495c5e11034e1b72e74c05 Mon Sep 17 00:00:00 2001 From: khizmax Date: Sun, 21 Sep 2014 19:06:52 +0400 Subject: [PATCH] Remove MichaelDeque --- cds/container/michael_deque.h | 493 --------- cds/intrusive/deque_stat.h | 82 -- cds/intrusive/michael_deque.h | 992 ------------------ projects/Win/vc12/cds.sln | 27 +- projects/Win/vc12/cds.vcxproj | 3 - projects/Win/vc12/cds.vcxproj.filters | 9 - projects/Win/vc12/hdr-test-deque.vcxproj | 8 - projects/Win/vc12/unit-prerequisites.vcxproj | 6 - tests/test-hdr/deque/hdr_deque.h | 390 ------- tests/test-hdr/deque/hdr_intrusive_deque.h | 334 ------ .../deque/hdr_intrusive_michael_deque_hp.cpp | 166 --- .../deque/hdr_intrusive_michael_deque_ptb.cpp | 142 --- tests/test-hdr/deque/hdr_michael_deque_hp.cpp | 45 - .../test-hdr/deque/hdr_michael_deque_ptb.cpp | 43 - tests/unit/print_deque_stat.h | 41 - tests/unit/queue/intrusive_queue_defs.h | 31 - tests/unit/queue/intrusive_queue_type.h | 117 --- tests/unit/queue/queue_defs.h | 39 - tests/unit/queue/queue_type.h | 114 -- tests/unit/stack/stack_intrusive_pushpop.cpp | 1 - tests/unit/stack/stack_push.cpp | 1 - tests/unit/stack/stack_pushpop.cpp | 1 - 22 files changed, 17 insertions(+), 3068 deletions(-) delete mode 100644 cds/container/michael_deque.h delete mode 100644 cds/intrusive/deque_stat.h delete mode 100644 cds/intrusive/michael_deque.h delete mode 100644 tests/test-hdr/deque/hdr_deque.h delete mode 100644 tests/test-hdr/deque/hdr_intrusive_deque.h delete mode 100644 tests/test-hdr/deque/hdr_intrusive_michael_deque_hp.cpp delete mode 100644 tests/test-hdr/deque/hdr_intrusive_michael_deque_ptb.cpp delete mode 100644 tests/test-hdr/deque/hdr_michael_deque_hp.cpp delete mode 100644 tests/test-hdr/deque/hdr_michael_deque_ptb.cpp delete mode 100644 tests/unit/print_deque_stat.h diff --git a/cds/container/michael_deque.h b/cds/container/michael_deque.h deleted file mode 100644 index bef5df18..00000000 --- a/cds/container/michael_deque.h +++ /dev/null @@ -1,493 +0,0 @@ -//$$CDS-header$$ - -#ifndef __CDS_CONTAINER_MICHAEL_DEQUE_H -#define __CDS_CONTAINER_MICHAEL_DEQUE_H - -#include -#include -#include - -namespace cds { namespace container { - - //@cond - namespace details { - template - struct make_michael_deque - { - typedef GC gc; - typedef T value_type; - - struct default_options - { - typedef cds::backoff::empty back_off; - typedef cds::atomicity::empty_item_counter item_counter; - typedef cds::intrusive::michael_deque::dummy_stat stat; - typedef cds::opt::v::relaxed_ordering memory_model; - enum { alignment = cds::opt::cache_line_alignment }; - typedef CDS_DEFAULT_ALLOCATOR allocator; - }; - - typedef typename cds::opt::make_options< - typename cds::opt::find_type_traits< default_options, CDS_OPTIONS7 >::type - ,CDS_OPTIONS7 - >::type options; - - struct node_type : public cds::intrusive::michael_deque::node< gc > - { - value_type m_value; - node_type() - {} - node_type(const value_type& val) - : m_value( val ) - {} -# ifdef CDS_EMPLACE_SUPPORT - template - node_type( Args&&... args ) - : m_value( std::forward(args)...) - {} -# endif - }; - - typedef typename options::allocator::template rebind::other allocator_type; - typedef cds::details::Allocator< node_type, allocator_type > cxx_allocator; - - struct node_deallocator - { - void operator ()( node_type * pNode ) - { - cxx_allocator().Delete( pNode ); - } - }; - - typedef cds::intrusive::MichaelDeque< gc, - node_type - ,cds::intrusive::opt::hook< - cds::intrusive::michael_deque::base_hook< cds::opt::gc > - > - ,cds::opt::back_off< typename options::back_off > - ,cds::intrusive::opt::disposer< node_deallocator > - ,cds::opt::item_counter< typename options::item_counter > - ,cds::opt::stat< typename options::stat > - ,cds::opt::alignment< options::alignment > - ,cds::opt::memory_model< typename options::memory_model > - > type; - }; - } - //@endcond - - /// Michael's deque - /** @ingroup cds_nonintrusive_deque - - Implementation of Michael's deque algorithm. - - \par Source: - [2003] Maged Michael "CAS-based Lock-free Algorithm for Shared Deque" - - Short description (from Michael's paper) - - The deque is represented as a doubly-linked list. Each node in the list contains two link pointers, - \p pRight and \p pLeft, and a data field. A shared variable, \p Anchor, holds the two anchor - pointers to the leftmost and rightmost nodes in the list, if any, and a three-value - status tag. Anchor must fit in a memory block that can be read and manipulated - using CAS or LL/SC, atomically. Initially both anchor pointers have null values - and the status tag holds the value stable, indicating an empty deque. - - The status tag serves to indicate if the deque is in an unstable state. When - a process finds the deque in an unstable state, it must first attempt to take it - to a stable state before attempting its own operation. - - The algorithm can use 64bit CAS. Instead of a pointer the node contains two - 31bit link indices + one bit for status tag; - this trick allows use 64bit CAS to manipulate \p Anchor. Internal mapper - (based on intrusive::MichaelHashSet intrusive container) - reflects link indices to item pointers. The maximum number of item in - the deque is limited by 2**31 - 1 that is practically unbounded. - - Template arguments: - - \p GC - garbage collector type: gc::HP, gc::PTB. Note that gc::HRC is NOT supported for this container. - - \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. - Used for item allocation. - - 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 that means no item counting feature - - opt::stat - the type to gather internal statistics. - Possible option value are: \ref intrusive::michael_deque::stat, \ref intrusive::michael_deque::dummy_stat, - user-provided class that supports intrusive::michael_deque::stat interface. - Default is \ref intrusive::michael_deque::dummy_stat. - - opt::alignment - the alignment for internal deque 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). - */ - template - class MichaelDeque: -#ifdef CDS_DOXYGEN_INVOKED - intrusive::MichaelDeque< GC, intrusive::michael_deque::node< T >, Options... > -#else - details::make_michael_deque< GC, T, CDS_OPTIONS7 >::type -#endif - { - //@cond - typedef details::make_michael_deque< GC, T, CDS_OPTIONS7 > options; - typedef typename options::type base_class; - //@endcond - - public: - /// Rebind template arguments - template - struct rebind { - typedef MichaelDeque< GC2, T2, CDS_OTHER_OPTIONS7> other ; ///< Rebinding result - }; - - public: - typedef T value_type ; ///< Value type stored in the deque - - 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 options::options::item_counter item_counter ; ///< Item counting policy used - typedef typename options::options::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) - - //@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; - //@endcond - - protected: - ///@cond - static node_type * alloc_node() - { - return cxx_allocator().New(); - } - static node_type * alloc_node( const value_type& val ) - { - return cxx_allocator().New( val ); - } -# ifdef CDS_EMPLACE_SUPPORT - template - static node_type * alloc_node( Args&&... args ) - { - return cxx_allocator().MoveNew( std::forward(args)... ); - } -# endif - static void free_node( node_type * p ) - { - node_deallocator()( p ); - } - - struct node_disposer { - void operator()( node_type * pNode ) - { - free_node( pNode ); - } - }; - typedef std::unique_ptr< node_type, node_disposer > scoped_node_ptr; - - bool push_node_back( node_type * pNode ) - { - assert( pNode != nullptr ); - scoped_node_ptr p(pNode); - - if ( base_class::push_back( *pNode ) ) { - p.release(); - return true; - } - return false; - } - - bool push_node_front( node_type * pNode ) - { - assert( pNode != nullptr ); - scoped_node_ptr p(pNode); - - if ( base_class::push_front( *pNode ) ) { - p.release(); - return true; - } - return false; - } - //@endcond - - public: - /// Default constructor - /** - Initializes the deque object that can contain up to 2**16 - 1 items - */ - MichaelDeque() - {} - - /// Constructor - /** - Initializes the deque object with estimated item count \p nMaxItemCount. - \p nLoadFactor is a parameter of internal memory mapper based on intrusive::MichaelHashSet; - see MichaelHashSet ctor for details - */ - MichaelDeque( unsigned int nMaxItemCount, unsigned int nLoadFactor = 4 ) - : base_class( nMaxItemCount, nLoadFactor ) - {} - - /// Destructor clears the deque - ~MichaelDeque() - {} - - public: - /// Push back (right) side - /** - Push new item \p val to right side of the deque. - */ - bool push_back( value_type const& val ) - { - return push_node_back( alloc_node( val )); - } - - /// Push back (right) side using copy 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 deque. - The functor's interface is: - \code - struct myFunctor { - void operator()(T& dest, Type 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. - - Requirements The functor \p Func should not throw any exception. - */ - template - bool push_back( Type const& val, Func f ) - { - scoped_node_ptr p( alloc_node()); - unref(f)( p->m_value, val ); - if ( base_class::push_back( *p )) { - p.release(); - return true; - } - return false; - } - -# ifdef CDS_EMPLACE_SUPPORT - /// Push back (right side) data of type \ref value_type constructed with std::forward(args)... - /** - Returns \p true if the oprration successful, \p false otherwise. - - This function is available only for compiler that supports - variadic template and move semantics - */ - template - bool emplace_back( Args&&... args ) - { - return push_node_back( alloc_node( std::forward(args)... )); - } -# endif - - /// Push front (left) side - /** - Push new item \p val to left side of the deque. - */ - bool push_front( value_type const& val ) - { - return push_node_front( alloc_node( val )); - } - - /// Push front side using copy 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 deque. - The functor's interface is: - \code - struct myFunctor { - void operator()(T& dest, Type 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. - - Requirements The functor \p Func should not throw any exception. - */ - template - bool push_front( Type const& val, Func f ) - { - scoped_node_ptr p( alloc_node()); - unref(f)( p->m_value, val ); - if ( base_class::push_front( *p )) { - p.release(); - return true; - } - return false; - } - -# ifdef CDS_EMPLACE_SUPPORT - /// Push front (left side) data of type \ref value_type constructed with std::forward(args)... - /** - Returns \p true if the operation successful, \p false otherwise. - - This function is available only for compiler that supports - variadic template and move semantics - */ - template - bool emplace_front( Args&&... args ) - { - return push_node_front( alloc_node( std::forward(args)... )); - } -# endif - - /// Pops back side, no return value - /** - The function returns \p true if the deque has not been empty (in other words, an item has been popped), - otherwise the function returns \p false. - */ - bool pop_back() - { - return base_class::pop_back() != nullptr; - } - - /// Pops back side a value using copy functor - /** - \p Func is a functor called to copy value popped to \p dest of type \p Type - which may be differ from type \p T stored in the deque. - 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. - - Requirements The functor \p Func should not throw any exception. - */ - template - bool pop_back( Type& dest, Func f ) - { - typename base_class::pop_result res; - if ( base_class::do_pop_back( res )) { - unref(f)( dest, node_traits::to_value_ptr( res.pPopped )->m_value ); - base_class::dispose_result( res ); - return true; - } - return false; - } - - - /// Pops back side, store value popped into \p dest - /** - If deque is not empty, the function returns \p true, \p dest contains copy of - value popped. The assignment operator for type \ref value_type is invoked. - If deque is empty, the function returns \p false, \p dest is unchanged. - */ - bool pop_back( value_type& dest ) - { - typedef cds::details::trivial_assign functor; - return pop_back( dest, functor() ); - } - - /// Pops front side, no return value - /** - The function returns \p true if the deque has not been empty (in other words, an item has been popped), - otherwise the function returns \p false. - */ - bool pop_front() - { - return base_class::pop_front() != nullptr; - } - - /// Pops front side a value using copy functor - /** - \p Func is a functor called to copy value popped to \p dest of type \p Type - which may be differ from type \p T stored in the deque. - 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. - - Requirements The functor \p Func should not throw any exception. - */ - template - bool pop_front( Type& dest, Func f ) - { - typename base_class::pop_result res; - if ( base_class::do_pop_front( res )) { - unref(f)( dest, node_traits::to_value_ptr( res.pPopped )->m_value ); - base_class::dispose_result( res ); - return true; - } - return false; - } - - - /// Pops front side, store value popped into \p dest - /** - If deque is not empty, the function returns \p true, \p dest contains copy of - value popped. The assignment operator for type \ref value_type is invoked. - If deque is empty, the function returns \p false, \p dest is unchanged. - */ - bool pop_front( value_type& dest ) - { - typedef cds::details::trivial_assign functor; - return pop_front( dest, functor() ); - } - - /// Returns deque's item count - /** - The value returned depends on opt::item_counter option. For atomicity::empty_item_counter, - this function always returns 0. - - Warning: even if you use real item counter and it returns 0, this fact does not mean that the deque - is empty. To check deque emptyness use \ref empty() method. - */ - size_t size() const - { - return base_class::size(); - } - - /// Checks if the dequeue is empty - bool empty() const - { - return base_class::empty(); - } - - /// Clear the deque - /** - The function repeatedly calls \ref pop_back until it returns \p nullptr. - */ - void clear() - { - return base_class::clear(); - } - - /// Returns reference to internal statistics - const stat& statistics() const - { - return base_class::statistics(); - } - }; - -}} // namespace cds::container - - -#endif // #ifndef __CDS_CONTAINER_MICHAEL_DEQUE_H diff --git a/cds/intrusive/deque_stat.h b/cds/intrusive/deque_stat.h deleted file mode 100644 index 7146542d..00000000 --- a/cds/intrusive/deque_stat.h +++ /dev/null @@ -1,82 +0,0 @@ -//$$CDS-header$$ - -#ifndef __CDS_INTRUSIVE_DEQUE_STAT_H -#define __CDS_INTRUSIVE_DEQUE_STAT_H - -#include - -namespace cds { namespace intrusive { - - /// Deque internal statistics. May be used for debugging or profiling - /** @ingroup cds_intrusive_helper - Template argument \p Counter defines type of counter. - Default is cds::atomics::event_counter. - You may use other counter type like as cds::atomics::item_counter, - or even integral type, for example, \p int. - */ - template - struct deque_stat - { - typedef Counter counter_type ; ///< Counter type - - counter_type m_PushFrontCount ; ///< push front event count - counter_type m_PushBackCount ; ///< push back event count - counter_type m_PopFrontCount ; ///< pop front event count - counter_type m_PopBackCount ; ///< pop back event count - counter_type m_PopEmptyCount ; ///< pop from empty deque event count - counter_type m_PushFrontContentionCount ; ///< \p push_front contention count - counter_type m_PushBackContentionCount ; ///< \p push_back contention count - counter_type m_PopFrontContentionCount ; ///< \p pop_front contention count - counter_type m_PopBackContentionCount ; ///< \p pop_back contention count - - /// Register \p push_front call - void onPushFront() { ++m_PushFrontCount; } - - /// Register \p push_back call - void onPushBack() { ++m_PushBackCount; } - - /// Register \p pop_front call - void onPopFront() { ++m_PopFrontCount; } - - /// Register \p pop_back call - void onPopBack() { ++m_PopBackCount; } - - /// Register popping from empty deque - void onPopEmpty() { ++m_PopEmptyCount; } - - /// Register "\p push_front contention" event - void onPushFrontContention() { ++m_PushFrontContentionCount; } - - /// Register "\p push_back contention" event - void onPushBackContention() { ++m_PushBackContentionCount; } - - /// Register "\p pop_front contention" event - void onPopFrontContention() { ++m_PopFrontContentionCount; } - - /// Register "\p pop_back contention" event - void onPopBackContention() { ++m_PopBackContentionCount; } - }; - - - /// Dummy deque statistics - no counting is performed. Support interface like \ref deque_stat - /** @ingroup cds_intrusive_helper - */ - struct deque_dummy_stat - { - //@cond - void onPushFront() {} - void onPushBack() {} - void onPopFront() {} - void onPopBack() {} - void onPopEmpty() {} - void onPushFrontContention() {} - void onPushBackContention() {} - void onPopFrontContention() {} - void onPopBackContention() {} - //@endcond - }; - -}} // namespace cds::intrusive - - -#endif // #ifndef __CDS_INTRUSIVE_DEQUE_STAT_H diff --git a/cds/intrusive/michael_deque.h b/cds/intrusive/michael_deque.h deleted file mode 100644 index 8de82e1e..00000000 --- a/cds/intrusive/michael_deque.h +++ /dev/null @@ -1,992 +0,0 @@ -//$$CDS-header$$ - -#ifndef __CDS_INTRUSIVE_MICHAEL_DEQUE_H -#define __CDS_INTRUSIVE_MICHAEL_DEQUE_H - -#include -#include -#include -#include -#include -#include -#include - -namespace cds { namespace intrusive { - - //@cond - struct michael_deque_tag; - //@endcond - - /// MichaelDeque related definitions - /** @ingroup cds_intrusive_helper - */ - namespace michael_deque - { - /// Anchor contains left/right sibling items - /** - The anchor object is maintained by one CAS instruction. - */ - struct anchor - { - unsigned int idxLeft ; ///< Left sibling index; the most-significant bit contains left-stable flag - unsigned int idxRight ; ///< Right sibling index; the most-significant bit contains right-stable flag - -# ifdef CDS_CXX11_EXPLICITLY_DEFAULTED_FUNCTION_SUPPORT - //@cond - anchor() CDS_NOEXCEPT_DEFAULTED = default; - anchor( anchor const& ) CDS_NOEXCEPT_DEFAULTED = default; - ~anchor() CDS_NOEXCEPT_DEFAULTED = default; - anchor& operator=(anchor const&) CDS_NOEXCEPT_DEFAULTED = default; -# if defined(CDS_MOVE_SEMANTICS_SUPPORT) && !defined(CDS_DISABLE_DEFAULT_MOVE_CTOR) - anchor( anchor&&) CDS_NOEXCEPT_DEFAULTED = default; - anchor& operator=(anchor&&) CDS_NOEXCEPT_DEFAULTED = default; -# endif - //@endcond -# else - /// Default ctor does not initialize left/right indices - anchor() CDS_NOEXCEPT - : idxLeft( 0 ) - , idxRight( 0 ) - { - static_check(); - } - - anchor( anchor const& a) CDS_NOEXCEPT - : idxLeft( a.idxLeft ) - , idxRight( a.idxRight ) - { - static_check(); - } -# endif - - /// Constructor sets \p left / \p right indices - anchor( unsigned int left, unsigned int right ) CDS_NOEXCEPT - : idxLeft( left ) - , idxRight( right ) - { - static_check(); - } - - /// Anchor equal operator - bool operator ==( anchor const& a) const CDS_NOEXCEPT - { - return idxLeft == a.idxLeft && idxRight == a.idxRight; - } - - /// Anchor non-equal operator - bool operator !=( anchor const& a) const CDS_NOEXCEPT - { - return !( *this == a ); - } - - private: - //@cond - static void static_check() - { - static_assert( sizeof(unsigned int) * 2 <= 8, "The index type must be no more than 32bit long" ); - static_assert( sizeof(anchor) <= 8, "The anchor type must be no more than 64bit long" ); - } - //@endcond - }; - - /// Michael's deque node - /** - Template parameters: - - GC - garbage collector - - Tag - a tag used to distinguish between different implementation - */ - template - struct node: public michael_list::node< GC, michael_deque_tag > - { - typedef GC gc ; ///< Garbage collector - typedef Tag tag ; ///< tag - - //@cond - typedef michael_list::node< gc, michael_deque_tag > mapper_node_type; - //@endcond - - typedef typename gc::template atomic_type< anchor > atomic_anchor ; ///< atomic reference to left/right node - - CDS_DATA_ALIGNMENT(8) atomic_anchor m_Links ; ///< Left/right sibling links - unsigned int m_nIndex; ///< Item index - - //@cond - node() - { - m_Links.store( anchor(0,0), atomics::memory_order_release ); - } - - explicit node( anchor const& a ) - : m_Links() - , m_nIndex(0) - { - m_Links.store( a, atomics::memory_order_release ); - } - //@endcond - }; - - //@cond - struct default_hook { - typedef cds::gc::default_gc gc; - typedef opt::none tag; - typedef unsigned int index_type; - }; - //@endcond - - //@cond - template < typename HookType, CDS_DECL_OPTIONS3> - struct hook - { - typedef typename opt::make_options< default_hook, CDS_OPTIONS3>::type options; - typedef typename options::gc gc; - typedef typename options::tag tag; - typedef typename options::index_type index_type; - - typedef node node_type; - typedef HookType hook_type; - }; - //@endcond - - - /// Base hook - /** - \p Options are: - - opt::gc - garbage collector used. - - opt::tag - tag - - opt::index_type - integral index type - */ - template < CDS_DECL_OPTIONS3 > - struct base_hook: public hook< opt::base_hook_tag, CDS_OPTIONS3 > - {}; - - /// Member hook - /** - \p MemberOffset defines offset in bytes of \ref node member into your structure. - Use \p offsetof macro to define \p MemberOffset - - \p Options are: - - opt::gc - garbage collector used. - - opt::tag - tag - - opt::index_type - integral index type - */ - template < size_t MemberOffset, CDS_DECL_OPTIONS3 > - struct member_hook: public hook< opt::member_hook_tag, CDS_OPTIONS3 > - { - //@cond - static const size_t c_nMemberOffset = MemberOffset; - //@endcond - }; - - /// Traits hook - /** - \p NodeTraits defines type traits for node. - See \ref node_traits for \p NodeTraits interface description - - \p Options are: - - opt::gc - garbage collector used. - - opt::tag - tag - - opt::index_type - integral index type - */ - template - struct traits_hook: public hook< opt::traits_hook_tag, CDS_OPTIONS3 > - { - //@cond - typedef NodeTraits node_traits; - //@endcond - }; - - /// Deque internal statistics. May be used for debugging or profiling - /** - Template argument \p Counter defines type of counter. - Default is cds::atomics::event_counter. - You may use other counter type like as cds::atomics::item_counter, - or even integral type, for example, \p int. - - The class extends intrusive::deque_stat interface for MichaelDeque. - */ - template - struct stat: public cds::intrusive::deque_stat - { - //@cond - typedef cds::intrusive::deque_stat base_class; - typedef typename base_class::counter_type counter_type; - //@endcond - - counter_type m_StabilizeFrontCount ; ///< stabilize left event count - counter_type m_StabilizeBackCount ; ///< stabilize right event count - - /// Register "stabilize left" event - void onStabilizeFront() { ++m_StabilizeFrontCount; } - - /// Register "stabilize right" event - void onStabilizeBack() { ++m_StabilizeBackCount; } - }; - - /// Dummy deque statistics - no counting is performed. Support interface like \ref michael_deque::stat - struct dummy_stat: public cds::intrusive::deque_dummy_stat - { - //@cond - void onStabilizeFront() {} - void onStabilizeBack() {} - //@endcond - }; - - //@cond - template < typename NodeType, opt::link_check_type LinkType> - struct link_checker - { - typedef NodeType node_type; - - static void is_empty( const node_type * pNode ) - { -# ifdef _DEBUG - anchor a = pNode->m_Links.load(atomics::memory_order_relaxed); - assert( a.idxLeft == 0 && a.idxRight == 0 ); -# endif - } - }; - - template < typename NodeType> - struct link_checker - { - typedef NodeType node_type; - - static void is_empty( const node_type * /*pNode*/ ) - {} - }; - //@endcond - } // namespace michael_deque - - /// Michael's intrusive deque - /** @ingroup cds_intrusive_deque - Implementation of Michael's deque algorithm. - - \par Source: - [2003] Maged Michael "CAS-based Lock-free Algorithm for Shared Deque" - - Short description (from Michael's paper) - - The deque is represented as a doubly-linked list. Each node in the list contains two link pointers, - \p pRight and \p pLeft, and a data field. A shared variable, \p Anchor, holds the two anchor - pointers to the leftmost and rightmost nodes in the list, if any, and a three-value - status tag. Anchor must fit in a memory block that can be read and manipulated - using CAS or LL/SC, atomically. Initially both anchor pointers have null values - and the status tag holds the value stable, indicating an empty deque. - - The status tag serves to indicate if the deque is in an unstable state. When - a process finds the deque in an unstable state, it must first attempt to take it - to a stable state before attempting its own operation. - - The algorithm can use single-word CAS or LL/SC. - In \p libcds implementation of the algorithm the node contains two - 31bit link indices instead of pointers + one bit for status tag; - this trick allows use 64bit CAS to manipulate \p Anchor. Internal mapper - (based on MichaelHashSet intrusive container) - reflects link indices to item pointers. The maximum number of item in - the deque is limited by 2**31 that is practically unbounded. - - Template arguments: - - \p GC - garbage collector type: gc::HP or gc::PTB. Note that gc::HRC is not supported - - \p T - type to be stored in the queue, should be convertible to michael_deque::node - - \p Options - options - - Type of node: \ref michael_deque::node - - \p Options are: - - opt::hook - hook used. Possible values are: michael_deque::base_hook, michael_deque::member_hook, michael_deque::traits_hook. - If the option is not specified, michael_deque::base_hook<> is used. - - opt::back_off - back-off strategy used. If the option is not specified, the cds::backoff::empty is used. - - opt::disposer - the functor used for dispose removed items. Default is opt::v::empty_disposer. This option is used - in \ref pop_front and \ref pop_back functions. - - opt::link_checker - the type of node's link fields checking. Default is \ref opt::debug_check_link - - opt::item_counter - the type of item counting feature. Default is \ref atomicity::empty_item_counter (no item counting feature) - - opt::stat - the type to gather internal statistics. - Possible option value are: \ref michael_deque::stat, \ref michael_deque::dummy_stat, user-provided class that supports michael_deque::stat interface. - Default is \ref michael_deque::dummy_stat. - - opt::alignment - the alignment for internal deque 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). - - opt::allocator - allocator using for internal memory mapper based on MichaelHashSet. Default is CDS_DEFAULT_ALLOCATOR. - */ - template - class MichaelDeque - { - //@cond - struct default_options - { - typedef cds::backoff::empty back_off; - typedef michael_deque::base_hook<> hook; - typedef opt::v::empty_disposer disposer; - typedef atomicity::empty_item_counter item_counter; - typedef michael_deque::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 }; - typedef CDS_DEFAULT_ALLOCATOR allocator; - }; - //@endcond - - public: - //@cond - typedef typename opt::make_options< - typename cds::opt::find_type_traits< default_options, CDS_OPTIONS10 >::type - ,CDS_OPTIONS10 - >::type options; - //@endcond - - private: - //@cond - typedef typename std::conditional< - std::is_same >::value - ,michael_deque::stat<> - ,typename std::conditional< - std::is_same::value - ,michael_deque::dummy_stat - ,typename options::stat - >::type - >::type stat_type_; - //@endcond - - - public: - typedef T value_type ; ///< type of value stored in the deque - 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 michael_deque::link_checker< node_type, options::link_checker > link_checker ; ///< link checker - - typedef GC gc ; ///< Garbage collector - typedef typename options::back_off back_off ; ///< back-off strategy - typedef typename options::item_counter item_counter ; ///< Item counting policy used - typedef stat_type_ stat ; ///< Internal statistics policy used - typedef typename options::memory_model memory_model; ///< Memory ordering. See cds::opt::memory_model option - typedef typename options::allocator allocator_type ; ///< Allocator using for internal memory mapping - - typedef typename node_type::atomic_anchor atomic_anchor ; ///< Atomic anchor - - protected: - //@cond - class index_mapper - { - struct node_less_comparator - { - bool operator ()( value_type const & n1, value_type const& n2) const - { - return node_traits::to_node_ptr(n1)->m_nIndex < node_traits::to_node_ptr(n2)->m_nIndex; - } - bool operator ()( unsigned int i, value_type const& n2) const - { - return i < node_traits::to_node_ptr(n2)->m_nIndex; - } - bool operator ()( value_type const & n1, unsigned int i) const - { - return node_traits::to_node_ptr(n1)->m_nIndex < i; - } - }; - - struct internal_disposer - { - void operator()( value_type * p ) - { - assert( p != nullptr ); - - MichaelDeque::clear_links( node_traits::to_node_ptr(p) ); - disposer()( p ); - } - }; - - struct mapper_node_traits - { - typedef typename node_type::mapper_node_type mapper_node_type; - - static mapper_node_type * to_node_ptr( value_type& v ) - { - return static_cast( node_traits::to_node_ptr(v) ); - } - - static mapper_node_type * to_node_ptr( value_type * v ) - { - return static_cast( node_traits::to_node_ptr(v) ); - } - - static mapper_node_type const * to_node_ptr( value_type const& v ) - { - return static_cast( node_traits::to_node_ptr(v) ); - } - - static mapper_node_type const * to_node_ptr( value_type const * v ) - { - return static_cast( node_traits::to_node_ptr(v) ); - } - - static value_type * to_value_ptr( mapper_node_type& n ) - { - return node_traits::to_value_ptr( static_cast(n)); - } - - static value_type * to_value_ptr( mapper_node_type * n ) - { - return node_traits::to_value_ptr( static_cast(n)); - } - - static const value_type * to_value_ptr( mapper_node_type const& n ) - { - return node_traits::to_value_ptr( static_cast(n)); - } - - static const value_type * to_value_ptr( mapper_node_type const * n ) - { - return node_traits::to_value_ptr( static_cast(n)); - } - }; - - typedef MichaelList< gc, value_type, - typename michael_list::make_traits< - opt::hook< michael_list::traits_hook< - mapper_node_traits - ,cds::opt::gc< gc > - ,cds::opt::tag > - > - ,opt::less< node_less_comparator > - ,opt::back_off< back_off > - ,opt::disposer< internal_disposer > - ,opt::memory_model< memory_model > - >::type - > mapper_ordered_list; - - struct mapper_hash { - size_t operator()( value_type const& v ) const - { - return cds::opt::v::hash()( node_traits::to_node_ptr(v)->m_nIndex ); - } - size_t operator()( unsigned int i ) const - { - return cds::opt::v::hash()(i); - } - }; - - typedef MichaelHashSet< gc, mapper_ordered_list, - typename michael_set::make_traits< - opt::hash< mapper_hash > - ,opt::allocator< allocator_type > - >::type - > mapper_type; - -# if !(defined(CDS_CXX11_LAMBDA_SUPPORT) && !((CDS_COMPILER == CDS_COMPILER_MSVC || CDS_COMPILER == CDS_COMPILER_INTEL) && _MSC_VER < 1700)) - struct at_functor { - node_type * pNode; - - at_functor() - : pNode( nullptr ) - {} - - void operator()( value_type& v, unsigned int nIdx ) - { - pNode = node_traits::to_node_ptr(v); - assert( pNode->m_nIndex == nIdx ); - } - }; -# endif - - mapper_type m_set; - atomics::atomic m_nLastIndex; - - public: - - index_mapper( size_t nEstimatedItemCount, size_t nLoadFactor ) - : m_set( nEstimatedItemCount, nLoadFactor ) - , m_nLastIndex(1) - {} - - unsigned int map( value_type& v ) - { - while ( true ) { - node_type * pNode = node_traits::to_node_ptr( v ); - pNode->m_nIndex = m_nLastIndex.fetch_add( 1, memory_model::memory_order_relaxed ); - if ( pNode->m_nIndex && m_set.insert( v )) - return pNode->m_nIndex; - } - } - - bool unmap( unsigned int nIdx ) - { - return m_set.erase( nIdx ); - } - - node_type * at( unsigned int nIdx ) - { -# if defined(CDS_CXX11_LAMBDA_SUPPORT) && !((CDS_COMPILER == CDS_COMPILER_MSVC ||CDS_COMPILER == CDS_COMPILER_INTEL) && _MSC_VER < 1700) - // MS VC++2010 bug: error C2955: 'cds::intrusive::node_traits' : use of class template requires template argument list - // see declaration of 'cds::intrusive::node_traits' - node_type * pNode = nullptr; - if ( m_set.find( nIdx, - [&pNode](value_type& v, unsigned int nIdx) { - pNode = node_traits::to_node_ptr(v); - assert( pNode->m_nIndex == nIdx ); - }) - ) - return pNode; -# else - at_functor f; - if ( m_set.find( nIdx, cds::ref(f) )) - return f.pNode; -# endif - return nullptr; - } - }; - //@endcond - public: - - /// Rebind template arguments - template - struct rebind { - typedef MichaelDeque< GC2, T2, CDS_OTHER_OPTIONS10> other ; ///< Rebinding result - }; - - protected: - typename cds::opt::details::alignment_setter< atomic_anchor, options::alignment >::type m_Anchor ; ///< Left/right heads - typename cds::opt::details::alignment_setter< index_mapper, options::alignment >::type m_Mapper ; ///< Memory mapper - - item_counter m_ItemCounter ; ///< item counter - stat m_Stat ; ///< Internal statistics - - //@cond - static const unsigned int c_nIndexMask = ((unsigned int)(0 - 1)) >> 1; - static const unsigned int c_nFlagMask = ((unsigned int)(1)) << (sizeof(unsigned int) * 8 - 1); - static const unsigned int c_nEmptyIndex = 0; - //@endcond - - private: - //@cond - typedef michael_deque::anchor CDS_TYPE_ALIGNMENT(8) anchor_type; - typedef intrusive::node_to_value node_to_value; - - static void clear_links( node_type * pNode ) - { - pNode->m_Links.store( anchor_type(), memory_model::memory_order_release ); - } - - enum anchor_status { - Stable, - RPush, - LPush - }; - - static anchor_status status( anchor_type const& a ) - { - if ( a.idxLeft & c_nFlagMask ) - return LPush; - if ( a.idxRight & c_nFlagMask ) - return RPush; - return Stable; - } - - static unsigned int index( unsigned int i ) - { - return i & c_nIndexMask; - } - - void stabilize( anchor_type& a ) - { - switch ( status(a)) { - case LPush: - stabilize_front(a); - break; - case RPush: - stabilize_back(a); - break; - default: - break; - } - } - - void stabilize_front( anchor_type& a ) - { - m_Stat.onStabilizeFront(); - - typename gc::template GuardArray<3> guards; - node_type * pLeft; - node_type * pRight; - unsigned int const idxLeft = index( a.idxLeft ); - unsigned int const idxRight = index( a.idxRight ); - - guards.assign( 0, node_traits::to_value_ptr( pLeft = m_Mapper.at( idxLeft )) ); - guards.assign( 1, node_traits::to_value_ptr( pRight = m_Mapper.at( idxRight )) ); - if ( m_Anchor.load( memory_model::memory_order_acquire ) != a ) - return; - - unsigned int idxPrev = index( pLeft->m_Links.load(memory_model::memory_order_relaxed ).idxRight ); - node_type * pPrev; - guards.assign( 2, node_traits::to_value_ptr( pPrev = m_Mapper.at( idxPrev )) ); - if ( m_Anchor.load( memory_model::memory_order_acquire ) != a ) - return; - - anchor_type prevLinks( pPrev->m_Links.load( memory_model::memory_order_acquire )); - if ( index( prevLinks.idxLeft ) != idxLeft ) { - if ( m_Anchor.load( memory_model::memory_order_acquire ) != a ) - return; - - if ( !pPrev->m_Links.compare_exchange_strong( prevLinks, anchor_type( idxLeft, prevLinks.idxRight ), memory_model::memory_order_release, memory_model::memory_order_relaxed )) - return; - } - - // clear RPush/LPush flags - m_Anchor.compare_exchange_weak( a, anchor_type(idxLeft, idxRight), memory_model::memory_order_release, memory_model::memory_order_relaxed ); - } - - void stabilize_back( anchor_type& a ) - { - m_Stat.onStabilizeBack(); - - typename gc::template GuardArray<3> guards; - node_type * pLeft; - node_type * pRight; - unsigned int const idxLeft = index( a.idxLeft ); - unsigned int const idxRight = index( a.idxRight ); - - guards.assign( 0, node_traits::to_value_ptr( pLeft = m_Mapper.at( idxLeft )) ); - guards.assign( 1, node_traits::to_value_ptr( pRight = m_Mapper.at( idxRight )) ); - if ( m_Anchor.load( memory_model::memory_order_acquire ) != a ) - return; - - unsigned int idxPrev = index( pRight->m_Links.load(memory_model::memory_order_relaxed ).idxLeft ); - node_type * pPrev; - guards.assign( 2, node_traits::to_value_ptr( pPrev = m_Mapper.at( idxPrev )) ); - if ( m_Anchor.load( memory_model::memory_order_acquire ) != a ) - return; - - anchor_type prevLinks( pPrev->m_Links.load( memory_model::memory_order_acquire )); - if ( index( prevLinks.idxRight ) != idxRight ) { - if ( m_Anchor.load( memory_model::memory_order_acquire ) != a ) - return; - - if ( !pPrev->m_Links.compare_exchange_strong( prevLinks, anchor_type( prevLinks.idxLeft, idxRight ), memory_model::memory_order_release, memory_model::memory_order_relaxed )) - return; - } - - // clear RPush/LPush flags - m_Anchor.compare_exchange_weak( a, anchor_type(idxLeft, idxRight), memory_model::memory_order_release, memory_model::memory_order_relaxed ); - } - - //@endcond - - protected: - //@cond - struct pop_result { - value_type * pPopped; - unsigned int nIdxPopped; - typename gc::template GuardArray<2> guards; - }; - - void dispose_result( pop_result& res ) - { - m_Mapper.unmap( res.nIdxPopped ); - } - - bool do_pop_back( pop_result& res ) - { - back_off bkoff; - anchor_type a; - - while ( true ) { - a = m_Anchor.load( memory_model::memory_order_acquire ); - - if ( a.idxRight == c_nEmptyIndex ) { - m_Stat.onPopEmpty(); - return false; - } - - if ( a.idxLeft == a.idxRight ) { - if ( m_Anchor.compare_exchange_weak( a, anchor_type( c_nEmptyIndex, c_nEmptyIndex ), memory_model::memory_order_release, memory_model::memory_order_relaxed )) - break; - bkoff(); - } - else if ( status( a ) == Stable ) { - unsigned int idxLeft = index( a.idxLeft ); - unsigned int idxRight = index( a.idxRight ); - node_type * pLeft; - res.guards.assign( 0, node_traits::to_value_ptr( pLeft = m_Mapper.at( idxLeft )) ); - node_type * pRight; - res.guards.assign( 1, node_traits::to_value_ptr( pRight = m_Mapper.at( idxRight )) ); - - if ( m_Anchor.load( memory_model::memory_order_acquire ) != a ) { - m_Stat.onPopBackContention(); - continue; - } - - unsigned int nPrev = pRight->m_Links.load( memory_model::memory_order_acquire ).idxLeft; - if ( m_Anchor.compare_exchange_weak( a, anchor_type( a.idxLeft, nPrev ), memory_model::memory_order_release, memory_model::memory_order_relaxed ) ) - break; - bkoff(); - m_Stat.onPopBackContention(); - } - else - stabilize( a ); - } - - res.nIdxPopped = a.idxRight; - res.pPopped = node_traits::to_value_ptr( m_Mapper.at( a.idxRight )); - - --m_ItemCounter; - m_Stat.onPopBack(); - - return true; - } - - bool do_pop_front( pop_result& res ) - { - back_off bkoff; - anchor_type a; - - while ( true ) { - a = m_Anchor.load( memory_model::memory_order_acquire ); - - if ( a.idxLeft == c_nEmptyIndex ) { - m_Stat.onPopEmpty(); - return false; - } - - if ( a.idxLeft == a.idxRight ) { - if ( m_Anchor.compare_exchange_weak( a, anchor_type( c_nEmptyIndex, c_nEmptyIndex ), memory_model::memory_order_release, memory_model::memory_order_relaxed )) - break; - bkoff(); - } - else if ( status( a ) == Stable ) { - unsigned int idxLeft = index( a.idxLeft ); - unsigned int idxRight = index( a.idxRight ); - node_type * pLeft; - res.guards.assign( 0, node_traits::to_value_ptr( pLeft = m_Mapper.at( idxLeft )) ); - node_type * pRight; - res.guards.assign( 1, node_traits::to_value_ptr( pRight = m_Mapper.at( idxRight )) ); - - if ( m_Anchor.load( memory_model::memory_order_acquire ) != a ) { - m_Stat.onPopFrontContention(); - continue; - } - - unsigned int nPrev = pLeft->m_Links.load( memory_model::memory_order_acquire ).idxRight; - if ( m_Anchor.compare_exchange_weak( a, anchor_type( nPrev, a.idxRight ), memory_model::memory_order_release, memory_model::memory_order_relaxed ) ) - break; - bkoff(); - m_Stat.onPopFrontContention(); - } - else - stabilize( a ); - } - - res.nIdxPopped = a.idxLeft; - res.pPopped = node_traits::to_value_ptr( m_Mapper.at( a.idxLeft )); - - --m_ItemCounter; - m_Stat.onPopFront(); - - return true; - } - - //@endcond - - public: - /// Default constructor - /** - Initializes the deque object with up to 2**16 - 2 items - */ - MichaelDeque() - :m_Anchor() - ,m_Mapper( 4096, 4 ) - { - m_Anchor.store( anchor_type( c_nEmptyIndex, c_nEmptyIndex ), atomics::memory_order_release ); - - // GC and node_type::gc must be the same - static_assert(( std::is_same::value ), "GC and node_type::gc must be the same"); - - // cds::gc::HRC is not allowed - static_assert(( !std::is_same::value ), "cds::gc::HRC is not allowed here"); - } - - /// Constructor - /** - Initializes the deque object with estimated item count \p nMaxItemCount. - \p nLoadFactor is a parameter of internal memory mapper based on MichaelHashSet; - see MichaelHashSet ctor for details - */ - MichaelDeque( unsigned int nMaxItemCount, unsigned int nLoadFactor = 4 ) - :m_Anchor() - ,m_Mapper( nMaxItemCount, nLoadFactor ) - { - m_Anchor.store( anchor_type( c_nEmptyIndex, c_nEmptyIndex ), atomics::memory_order_release ); - - // GC and node_type::gc must be the same - static_assert(( std::is_same::value ), "GC and node_type::gc must be the same"); - - // cds::gc::HRC is not allowed - static_assert(( !std::is_same::value ), "cds::gc::HRC is not allowed here"); - } - - /// Destructor clears the deque - ~MichaelDeque() - { - clear(); - } - - public: - /// Push back (right) side - /** - Push new item \p val to right side of the deque. - */ - bool push_back( value_type& val ) - { - back_off bkoff; - - node_type * pNode = node_traits::to_node_ptr( val ); - link_checker::is_empty( pNode ); - - unsigned int nIdx = m_Mapper.map( val ); - if ( nIdx == c_nEmptyIndex ) - return false; - - while ( true ) { - anchor_type a = m_Anchor.load( memory_model::memory_order_acquire ); - if ( a.idxRight == c_nEmptyIndex ) { - if ( m_Anchor.compare_exchange_weak( a, anchor_type( nIdx, nIdx ), memory_model::memory_order_release, memory_model::memory_order_relaxed )) - break; - bkoff(); - m_Stat.onPushBackContention(); - } - else if ( status(a) == Stable ) { - pNode->m_Links.store( anchor_type( a.idxRight, c_nEmptyIndex ), memory_model::memory_order_release ); - anchor_type aNew( a.idxLeft, nIdx | c_nFlagMask ); - if ( m_Anchor.compare_exchange_weak( a, aNew, memory_model::memory_order_release, memory_model::memory_order_relaxed) ) { - stabilize_back( aNew ); - break; - } - bkoff(); - m_Stat.onPushBackContention(); - } - else - stabilize( a ); - } - - ++m_ItemCounter; - m_Stat.onPushBack(); - return true; - } - - /// Push front (left) side - /** - Push new item \p val to left side of the deque. - */ - bool push_front( value_type& val ) - { - back_off bkoff; - node_type * pNode = node_traits::to_node_ptr( val ); - link_checker::is_empty( pNode ); - - unsigned int nIdx = m_Mapper.map( val ); - if ( nIdx == c_nEmptyIndex ) - return false; - - while ( true ) { - anchor_type a = m_Anchor.load( memory_model::memory_order_acquire ); - if ( a.idxLeft == c_nEmptyIndex ) { - if ( m_Anchor.compare_exchange_weak( a, anchor_type( nIdx, nIdx ), memory_model::memory_order_release, memory_model::memory_order_relaxed )) - break; - bkoff(); - m_Stat.onPushFrontContention(); - } - else if ( status(a) == Stable ) { - pNode->m_Links.store( anchor_type( c_nEmptyIndex, a.idxLeft ), memory_model::memory_order_release ); - anchor_type aNew( nIdx | c_nFlagMask, a.idxRight ); - if ( m_Anchor.compare_exchange_weak( a, aNew, memory_model::memory_order_release, memory_model::memory_order_relaxed )) { - stabilize_front( aNew ); - break; - } - bkoff(); - m_Stat.onPushFrontContention(); - } - else - stabilize( a ); - } - - ++m_ItemCounter; - m_Stat.onPushFront(); - return true; - } - - /// Pop back - /** - Pops rightmost item from the deque. If the deque is empty then returns \p nullptr. - - For popped object the disposer specified in \p Options template parameters is called. - */ - value_type * pop_back() - { - pop_result res; - if ( do_pop_back( res )) { - dispose_result( res ); - return res.pPopped; - } - - return nullptr; - } - - /// Pop front - /** - Pops leftmost item from the deque. If the deque is empty then returns \p nullptr. - - For popped object the disposer specified in \p Options template parameters is called. - */ - value_type * pop_front() - { - pop_result res; - if ( do_pop_front( res )) { - dispose_result( res ); - return res.pPopped; - } - - return nullptr; - } - - /// Returns deque's item count - /** - The value returned depends on opt::item_counter option. For atomicity::empty_item_counter, - this function always returns 0. - - Warning: even if you use real item counter and it returns 0, this fact does not mean that the deque - is empty. To check deque emptyness use \ref empty() method. - */ - size_t size() const - { - return m_ItemCounter.value(); - } - - /// Checks if the dequeue is empty - bool empty() const - { - anchor_type a = m_Anchor.load( memory_model::memory_order_relaxed ); - return a.idxLeft == c_nEmptyIndex && a.idxRight == c_nEmptyIndex; - } - - /// Clear the deque - /** - The function repeatedly calls \ref pop_back until it returns \p nullptr. - The disposer defined in template \p Options is called for each item - that can be safely disposed. - */ - void clear() - { - while ( pop_back() != nullptr ); - } - - /// Returns reference to internal statistics - const stat& statistics() const - { - return m_Stat; - } - }; - - -}} // namespace cds::intrusive - - -#endif // #ifndef __CDS_INTRUSIVE_MICHAEL_DEQUE_H diff --git a/projects/Win/vc12/cds.sln b/projects/Win/vc12/cds.sln index 46adbef2..33eba274 100644 --- a/projects/Win/vc12/cds.sln +++ b/projects/Win/vc12/cds.sln @@ -1,10 +1,17 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.21005.1 +# Visual Studio Express 2013 for Windows Desktop +VisualStudioVersion = 12.0.30723.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cds", "cds.vcxproj", "{408FE9BC-44F0-4E6A-89FA-D6F952584239}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "unit-test", "unit-test", "{B30CA283-1796-4763-92C3-2E4848D443F7}" + ProjectSection(SolutionItems) = preProject + ..\..\..\tests\unit\print_cuckoo_stat.h = ..\..\..\tests\unit\print_cuckoo_stat.h + ..\..\..\tests\unit\print_ellenbintree_stat.h = ..\..\..\tests\unit\print_ellenbintree_stat.h + ..\..\..\tests\unit\print_mspriorityqueue_stat.h = ..\..\..\tests\unit\print_mspriorityqueue_stat.h + ..\..\..\tests\unit\print_segmentedqueue_stat.h = ..\..\..\tests\unit\print_segmentedqueue_stat.h + ..\..\..\tests\unit\print_skip_list_stat.h = ..\..\..\tests\unit\print_skip_list_stat.h + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unit-prerequisites", "unit-prerequisites.vcxproj", "{61179F2F-07E1-490D-B64D-D85A90B6EF81}" ProjectSection(ProjectDependencies) = postProject @@ -594,24 +601,24 @@ Global {77350FDC-9E51-438B-9A8F-D2FEA11D46B2} = {B30CA283-1796-4763-92C3-2E4848D443F7} {6C15AF8A-4A99-49F9-BCF0-1BF36771099A} = {B30CA283-1796-4763-92C3-2E4848D443F7} {E29DE1F7-AE8D-4AE6-98B1-147E5103D974} = {B30CA283-1796-4763-92C3-2E4848D443F7} - {6BB7A27F-FC59-4267-B6FA-D034176D1459} = {B30CA283-1796-4763-92C3-2E4848D443F7} - {A64449B7-90FB-4E2B-A686-9EFC0E298644} = {B30CA283-1796-4763-92C3-2E4848D443F7} - {20B6C380-E96A-4CFF-BC17-D88AAE581919} = {B30CA283-1796-4763-92C3-2E4848D443F7} {CD0BC7FC-9BFF-40B0-8E66-99D244A8A026} = {B8C24D26-A3BF-4DA6-B64C-142CBA4BFE75} {282E9A9A-386A-40FB-A483-994BACE24830} = {B8C24D26-A3BF-4DA6-B64C-142CBA4BFE75} {C5E76975-B87B-4B9E-8596-B01DDA683FCA} = {B8C24D26-A3BF-4DA6-B64C-142CBA4BFE75} {EFCBBADE-2CF4-4E2B-ADB2-98C8D139E805} = {B8C24D26-A3BF-4DA6-B64C-142CBA4BFE75} + {6BB7A27F-FC59-4267-B6FA-D034176D1459} = {B30CA283-1796-4763-92C3-2E4848D443F7} + {A64449B7-90FB-4E2B-A686-9EFC0E298644} = {B30CA283-1796-4763-92C3-2E4848D443F7} + {3C598F96-FB84-4D42-9B43-F697F53B0221} = {6BB7A27F-FC59-4267-B6FA-D034176D1459} + {BA2A9239-0299-4069-BB0E-16DACE87ADE0} = {6BB7A27F-FC59-4267-B6FA-D034176D1459} + {CA25BDBF-B354-4597-B6D2-220ABBB0D2F4} = {6BB7A27F-FC59-4267-B6FA-D034176D1459} + {AF7B2253-2E6D-4992-94D9-4B3699C54929} = {A64449B7-90FB-4E2B-A686-9EFC0E298644} + {BA23811C-D4CB-4836-B2F3-6791BD6FFCD1} = {A64449B7-90FB-4E2B-A686-9EFC0E298644} {90192F7D-5850-41DD-AE89-62D26B387162} = {B8C24D26-A3BF-4DA6-B64C-142CBA4BFE75} {33664E63-8D24-4FF4-A744-9782EB711509} = {B8C24D26-A3BF-4DA6-B64C-142CBA4BFE75} {E5E9DB4A-7816-45D4-A116-6BBBA0EE8EE7} = {B8C24D26-A3BF-4DA6-B64C-142CBA4BFE75} {E3F2927A-6ED6-4B18-BDE6-B3B760E1AF18} = {B8C24D26-A3BF-4DA6-B64C-142CBA4BFE75} {A38E5597-6916-4480-A343-C9846EF544E4} = {B8C24D26-A3BF-4DA6-B64C-142CBA4BFE75} {6F834EAD-7B94-4979-A0F1-A662E3D30145} = {B8C24D26-A3BF-4DA6-B64C-142CBA4BFE75} - {3C598F96-FB84-4D42-9B43-F697F53B0221} = {6BB7A27F-FC59-4267-B6FA-D034176D1459} - {BA2A9239-0299-4069-BB0E-16DACE87ADE0} = {6BB7A27F-FC59-4267-B6FA-D034176D1459} - {CA25BDBF-B354-4597-B6D2-220ABBB0D2F4} = {6BB7A27F-FC59-4267-B6FA-D034176D1459} - {AF7B2253-2E6D-4992-94D9-4B3699C54929} = {A64449B7-90FB-4E2B-A686-9EFC0E298644} - {BA23811C-D4CB-4836-B2F3-6791BD6FFCD1} = {A64449B7-90FB-4E2B-A686-9EFC0E298644} + {20B6C380-E96A-4CFF-BC17-D88AAE581919} = {B30CA283-1796-4763-92C3-2E4848D443F7} EndGlobalSection GlobalSection(DPCodeReviewSolutionGUID) = preSolution DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000} diff --git a/projects/Win/vc12/cds.vcxproj b/projects/Win/vc12/cds.vcxproj index b5cad061..2c887aed 100644 --- a/projects/Win/vc12/cds.vcxproj +++ b/projects/Win/vc12/cds.vcxproj @@ -670,7 +670,6 @@ - @@ -738,7 +737,6 @@ - @@ -746,7 +744,6 @@ - diff --git a/projects/Win/vc12/cds.vcxproj.filters b/projects/Win/vc12/cds.vcxproj.filters index 7c055fa8..8bd0824a 100644 --- a/projects/Win/vc12/cds.vcxproj.filters +++ b/projects/Win/vc12/cds.vcxproj.filters @@ -848,24 +848,15 @@ Header Files\cds\compiler\clang - - Header Files\cds\intrusive - Header Files\cds\memory - - Header Files\cds\container - Header Files\cds\intrusive Header Files\cds\container - - Header Files\cds\intrusive - Header Files\cds\intrusive diff --git a/projects/Win/vc12/hdr-test-deque.vcxproj b/projects/Win/vc12/hdr-test-deque.vcxproj index 6e3fad1c..50aac2f0 100644 --- a/projects/Win/vc12/hdr-test-deque.vcxproj +++ b/projects/Win/vc12/hdr-test-deque.vcxproj @@ -544,16 +544,8 @@ MachineX64 - - - - - - - - diff --git a/projects/Win/vc12/unit-prerequisites.vcxproj b/projects/Win/vc12/unit-prerequisites.vcxproj index 20e597b4..dd5bfac2 100644 --- a/projects/Win/vc12/unit-prerequisites.vcxproj +++ b/projects/Win/vc12/unit-prerequisites.vcxproj @@ -417,14 +417,8 @@ - - - - - - diff --git a/tests/test-hdr/deque/hdr_deque.h b/tests/test-hdr/deque/hdr_deque.h deleted file mode 100644 index 7f9862e8..00000000 --- a/tests/test-hdr/deque/hdr_deque.h +++ /dev/null @@ -1,390 +0,0 @@ -//$$CDS-header$$ - -#include "cppunit/cppunit_proxy.h" -#include "cppunit/test_beans.h" - -namespace deque { - - class DequeHeaderTest: public CppUnitMini::TestCase - { - public: - struct value_type { - int nVal; - - value_type() - {} - value_type( int i ) - : nVal(i) - {} - }; - - struct assign_functor - { - template - void operator()( value_type& dest, T i ) const - { - dest.nVal = i; - } - }; - - struct pop_functor - { - template - void operator()( T& dest, value_type const& v ) - { - dest = v.nVal; - } - }; - - static void assign_func( value_type& dest, int i ) - { - dest.nVal = i; - } - static void pop_func( int& dest, value_type const& v ) - { - dest = v.nVal; - } - - template - void test() - { - test_beans::check_item_counter check_ic; - - Deque q; - value_type v; - int i; - - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); - - // push_right/pop_right - CPPUNIT_ASSERT( q.push_back( value_type(5) )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.push_back( 10, assign_functor() )) ; // functor - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - - CPPUNIT_ASSERT( q.push_back( 20, assign_func )) ; // function - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 3 )); - - CPPUNIT_ASSERT( q.pop_back(v) ); - CPPUNIT_ASSERT( v.nVal == 20 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - - CPPUNIT_ASSERT( q.pop_back( i, pop_functor()) ); - CPPUNIT_ASSERT( i == 10 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.pop_back(i, pop_func) ); - CPPUNIT_ASSERT( i == 5 ); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); - - v.nVal = -1; - CPPUNIT_ASSERT( !q.pop_back(v) ); - CPPUNIT_ASSERT( v.nVal == -1 ); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); - -#ifdef CDS_EMPLACE_SUPPORT - CPPUNIT_ASSERT( q.emplace_back( 157 )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.emplace_back( 158 )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - - CPPUNIT_ASSERT( q.pop_back(i, pop_func) ); - CPPUNIT_ASSERT( i == 158 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.pop_back(i, pop_functor()) ); - CPPUNIT_ASSERT( i == 157 ); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); -#endif - -#ifdef CDS_CXX11_LAMBDA_SUPPORT - CPPUNIT_ASSERT( q.push_back( value_type(511), [](value_type& dest, value_type const& i){ dest.nVal = i.nVal * 2; } )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.push_back( 512, [](value_type& dest, int i){ dest.nVal = i; } )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - - CPPUNIT_ASSERT( q.pop_back( i, []( int& dest, value_type const& v){ dest = v.nVal; } ) ); - CPPUNIT_ASSERT( i == 512 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - v.nVal = i = 0; - CPPUNIT_ASSERT( q.pop_back( i, [&v]( int& dest, value_type const& val){ dest = -val.nVal; v.nVal = val.nVal; }) ); - CPPUNIT_ASSERT( i == -511 * 2 ); - CPPUNIT_ASSERT( v.nVal == 511 * 2); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); -#endif - - // push_right/pop_left - CPPUNIT_ASSERT( q.push_back( value_type(5) )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.push_back( 10, assign_functor() )) ; // functor - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - - CPPUNIT_ASSERT( q.push_back( 20, assign_func )) ; // function - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 3 )); - - CPPUNIT_ASSERT( q.pop_front(v) ); - CPPUNIT_ASSERT( v.nVal == 5 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - - CPPUNIT_ASSERT( q.pop_front(i, pop_functor() ) ); - CPPUNIT_ASSERT( i == 10 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.pop_front( i, pop_func ) ); - CPPUNIT_ASSERT( i == 20 ); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); - - v.nVal = -1; - CPPUNIT_ASSERT( !q.pop_back(v) ); - CPPUNIT_ASSERT( v.nVal == -1 ); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); - -#ifdef CDS_EMPLACE_SUPPORT - CPPUNIT_ASSERT( q.emplace_back( 157 )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.emplace_back( 158 )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - - CPPUNIT_ASSERT( q.pop_front(i, pop_func) ); - CPPUNIT_ASSERT( i == 157 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.pop_front(i, pop_functor()) ); - CPPUNIT_ASSERT( i == 158 ); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); -#endif - -#ifdef CDS_CXX11_LAMBDA_SUPPORT - CPPUNIT_ASSERT( q.push_back( value_type(511), [](value_type& dest, value_type const& i){ dest.nVal = i.nVal * 2; } )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.push_back( 512, [](value_type& dest, int i){ dest.nVal = i; } )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - - CPPUNIT_ASSERT( q.pop_front( i, []( int& dest, value_type const& v){ dest = v.nVal; } ) ); - CPPUNIT_ASSERT( i == 511 * 2 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - v.nVal = i = 0; - CPPUNIT_ASSERT( q.pop_front( i, [&v]( int& dest, value_type const& val){ dest = -val.nVal; v.nVal = val.nVal; }) ); - CPPUNIT_ASSERT( i == -512 ); - CPPUNIT_ASSERT( v.nVal == 512); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); -#endif - - - // push_left/pop_left - CPPUNIT_ASSERT( q.push_front( value_type(5) )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.push_front( 10, assign_functor() )) ; // functor - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - - CPPUNIT_ASSERT( q.push_front( 20, assign_func )) ; // function - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 3 )); - - CPPUNIT_ASSERT( q.pop_front(v) ); - CPPUNIT_ASSERT( v.nVal == 20 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - - CPPUNIT_ASSERT( q.pop_front(v) ); - CPPUNIT_ASSERT( v.nVal == 10 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.pop_front(v) ); - CPPUNIT_ASSERT( v.nVal == 5 ); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); - -#ifdef CDS_EMPLACE_SUPPORT - CPPUNIT_ASSERT( q.emplace_front( 157 )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.emplace_front( 158 )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - - CPPUNIT_ASSERT( q.pop_front(i, pop_func) ); - CPPUNIT_ASSERT( i == 158 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.pop_front(i, pop_functor()) ); - CPPUNIT_ASSERT( i == 157 ); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); -#endif - -#ifdef CDS_CXX11_LAMBDA_SUPPORT - CPPUNIT_ASSERT( q.push_front( value_type(511), [](value_type& dest, value_type const& i){ dest.nVal = i.nVal * 2; } )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.push_front( 512, [](value_type& dest, int i){ dest.nVal = i; } )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - - CPPUNIT_ASSERT( q.pop_front( i, []( int& dest, value_type const& v){ dest = v.nVal; } ) ); - CPPUNIT_ASSERT( i == 512 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - v.nVal = i = 0; - CPPUNIT_ASSERT( q.pop_front( i, [&v]( int& dest, value_type const& val){ dest = -val.nVal; v.nVal = val.nVal; }) ); - CPPUNIT_ASSERT( i == -511 * 2 ); - CPPUNIT_ASSERT( v.nVal == 511 * 2); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); -#endif - - // push_left/pop_right - CPPUNIT_ASSERT( q.push_front( value_type(5) )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.push_front( 10, assign_functor() )) ; // functor - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - - CPPUNIT_ASSERT( q.push_front( 20, assign_func )) ; // function - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 3 )); - - CPPUNIT_ASSERT( q.pop_back(v) ); - CPPUNIT_ASSERT( v.nVal == 5 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - - CPPUNIT_ASSERT( q.pop_back(v) ); - CPPUNIT_ASSERT( v.nVal == 10 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.pop_back(v) ); - CPPUNIT_ASSERT( v.nVal == 20 ); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); - -#ifdef CDS_EMPLACE_SUPPORT - CPPUNIT_ASSERT( q.emplace_front( 157 )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.emplace_front( 158 )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - - CPPUNIT_ASSERT( q.pop_back(i, pop_func) ); - CPPUNIT_ASSERT( i == 157 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.pop_back(i, pop_functor()) ); - CPPUNIT_ASSERT( i == 158 ); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); -#endif - -#ifdef CDS_CXX11_LAMBDA_SUPPORT - CPPUNIT_ASSERT( q.push_front( value_type(511), [](value_type& dest, value_type const& i){ dest.nVal = i.nVal * 2; } )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - CPPUNIT_ASSERT( q.push_front( 512, [](value_type& dest, int i){ dest.nVal = i * 3; } )); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - - CPPUNIT_ASSERT( q.pop_back( i, []( int& dest, value_type const& v){ dest = v.nVal; } ) ); - CPPUNIT_ASSERT( i == 511 * 2 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - - v.nVal = i = 0; - CPPUNIT_ASSERT( q.pop_back( i, [&v]( int& dest, value_type const& val){ dest = -val.nVal; v.nVal = val.nVal; }) ); - CPPUNIT_ASSERT( i == -512 * 3 ); - CPPUNIT_ASSERT( v.nVal == 512 * 3); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); -#endif - - // clear test - for ( int i = 0; i < 1000; i++ ) { - CPPUNIT_ASSERT( q.push_back( value_type(i) )); - CPPUNIT_ASSERT( q.push_front( value_type(i * 1024) )); - } - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2000 )); - q.clear(); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); - - } - - void test_MichaelDeque_HP(); - void test_MichaelDeque_HP_ic(); - void test_MichaelDeque_HP_stat(); - void test_MichaelDeque_HP_noalign(); - - void test_MichaelDeque_PTB(); - void test_MichaelDeque_PTB_ic(); - void test_MichaelDeque_PTB_stat(); - void test_MichaelDeque_PTB_noalign(); - - CPPUNIT_TEST_SUITE(DequeHeaderTest) - CPPUNIT_TEST( test_MichaelDeque_HP); - CPPUNIT_TEST( test_MichaelDeque_HP_ic); - CPPUNIT_TEST( test_MichaelDeque_HP_stat); - CPPUNIT_TEST( test_MichaelDeque_HP_noalign); - - CPPUNIT_TEST( test_MichaelDeque_PTB); - CPPUNIT_TEST( test_MichaelDeque_PTB_ic); - CPPUNIT_TEST( test_MichaelDeque_PTB_stat); - CPPUNIT_TEST( test_MichaelDeque_PTB_noalign); - - CPPUNIT_TEST_SUITE_END() - - }; -} // namespace deque diff --git a/tests/test-hdr/deque/hdr_intrusive_deque.h b/tests/test-hdr/deque/hdr_intrusive_deque.h deleted file mode 100644 index 016b4846..00000000 --- a/tests/test-hdr/deque/hdr_intrusive_deque.h +++ /dev/null @@ -1,334 +0,0 @@ -//$$CDS-header$$ - -#include "cppunit/cppunit_proxy.h" -#include "cppunit/test_beans.h" - -namespace deque { - namespace ci = cds::intrusive; - namespace co = cds::opt; - - class IntrusiveDequeHeaderTest: public CppUnitMini::TestCase - { - public: - template - struct base_hook_item: public NodeType - { - int nVal; - int nDisposeCount; - - base_hook_item() - : nDisposeCount(0) - {} - }; - - template - struct member_hook_item - { - int nVal; - int nDisposeCount; - NodeType hMember; - - member_hook_item() - : nDisposeCount(0) - {} - }; - - struct faked_disposer - { - template - void operator ()( T * p ) - { - ++p->nDisposeCount; - } - }; - - template - void test() - { - test_beans::check_item_counter check_ic; - - typedef typename Deque::value_type value_type; - value_type v1, v2, v3; - - Deque q; - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); - - v1.nVal = 1; - v2.nVal = 2; - v3.nVal = 3; - - // push_left / pop_right - CPPUNIT_ASSERT( q.push_front(v1)); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - CPPUNIT_ASSERT( q.push_front(v2)); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - CPPUNIT_ASSERT( q.push_front(v3)); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 3 )); - - CPPUNIT_ASSERT( v1.nDisposeCount == 0 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 0 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 0 ); - - value_type * pv; - pv = q.pop_back(); - Deque::gc::scan(); - CPPUNIT_ASSERT( pv != nullptr ); - CPPUNIT_ASSERT( pv->nVal == 1 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - CPPUNIT_ASSERT( v1.nDisposeCount == 1 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 0 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 0 ); - - pv = q.pop_back(); - Deque::gc::scan(); - CPPUNIT_ASSERT( pv != nullptr ); - CPPUNIT_ASSERT( pv->nVal == 2 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - CPPUNIT_ASSERT( v1.nDisposeCount == 1 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 1 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 0 ); - - pv = q.pop_back(); - Deque::gc::scan(); - CPPUNIT_ASSERT( pv != nullptr ); - CPPUNIT_ASSERT( pv->nVal == 3 ); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); - CPPUNIT_ASSERT( v1.nDisposeCount == 1 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 1 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 1 ); - - pv = q.pop_back(); - Deque::gc::scan(); - CPPUNIT_ASSERT( pv == nullptr ); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); - CPPUNIT_ASSERT( v1.nDisposeCount == 1 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 1 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 1 ); - - - // push_right / pop_left - CPPUNIT_ASSERT( q.push_back(v1)); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - CPPUNIT_ASSERT( q.push_back(v2)); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - CPPUNIT_ASSERT( q.push_back(v3)); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 3 )); - - CPPUNIT_ASSERT( v1.nDisposeCount == 1 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 1 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 1 ); - - pv = q.pop_front(); - Deque::gc::scan(); - CPPUNIT_ASSERT( pv != nullptr ); - CPPUNIT_ASSERT( pv->nVal == 1 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - CPPUNIT_ASSERT( v1.nDisposeCount == 2 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 1 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 1 ); - - pv = q.pop_front(); - Deque::gc::scan(); - CPPUNIT_ASSERT( pv != nullptr ); - CPPUNIT_ASSERT( pv->nVal == 2 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - CPPUNIT_ASSERT( v1.nDisposeCount == 2 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 2 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 1 ); - - pv = q.pop_front(); - Deque::gc::scan(); - CPPUNIT_ASSERT( pv != nullptr ); - CPPUNIT_ASSERT( pv->nVal == 3 ); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); - CPPUNIT_ASSERT( v1.nDisposeCount == 2 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 2 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 2 ); - - pv = q.pop_front(); - Deque::gc::scan(); - CPPUNIT_ASSERT( pv == nullptr ); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); - CPPUNIT_ASSERT( v1.nDisposeCount == 2 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 2 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 2 ); - - - // push_right / pop_right - CPPUNIT_ASSERT( q.push_back(v1)); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - CPPUNIT_ASSERT( q.push_back(v2)); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - CPPUNIT_ASSERT( q.push_back(v3)); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 3 )); - - CPPUNIT_ASSERT( v1.nDisposeCount == 2 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 2 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 2 ); - - pv = q.pop_back(); - Deque::gc::scan(); - CPPUNIT_ASSERT( pv != nullptr ); - CPPUNIT_ASSERT( pv->nVal == 3 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - CPPUNIT_ASSERT( v1.nDisposeCount == 2 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 2 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 3 ); - - pv = q.pop_back(); - Deque::gc::scan(); - CPPUNIT_ASSERT( pv != nullptr ); - CPPUNIT_ASSERT( pv->nVal == 2 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - CPPUNIT_ASSERT( v1.nDisposeCount == 2 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 3 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 3 ); - - pv = q.pop_back(); - Deque::gc::scan(); - CPPUNIT_ASSERT( pv != nullptr ); - CPPUNIT_ASSERT( pv->nVal == 1 ); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); - CPPUNIT_ASSERT( v1.nDisposeCount == 3 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 3 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 3 ); - - pv = q.pop_back(); - Deque::gc::scan(); - CPPUNIT_ASSERT( pv == nullptr ); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); - CPPUNIT_ASSERT( v1.nDisposeCount == 3 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 3 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 3 ); - - - // push_left / pop_left - CPPUNIT_ASSERT( q.push_front(v1)); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - CPPUNIT_ASSERT( q.push_front(v2)); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - CPPUNIT_ASSERT( q.push_front(v3)); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 3 )); - - CPPUNIT_ASSERT( v1.nDisposeCount == 3 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 3 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 3 ); - - pv = q.pop_front(); - Deque::gc::scan(); - CPPUNIT_ASSERT( pv != nullptr ); - CPPUNIT_ASSERT( pv->nVal == 3 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 2 )); - CPPUNIT_ASSERT( v1.nDisposeCount == 3 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 3 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 4 ); - - pv = q.pop_front(); - Deque::gc::scan(); - CPPUNIT_ASSERT( pv != nullptr ); - CPPUNIT_ASSERT( pv->nVal == 2 ); - CPPUNIT_ASSERT( !q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 1 )); - CPPUNIT_ASSERT( v1.nDisposeCount == 3 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 4 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 4 ); - - pv = q.pop_front(); - Deque::gc::scan(); - CPPUNIT_ASSERT( pv != nullptr ); - CPPUNIT_ASSERT( pv->nVal == 1 ); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); - CPPUNIT_ASSERT( v1.nDisposeCount == 4 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 4 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 4 ); - - pv = q.pop_front(); - Deque::gc::scan(); - CPPUNIT_ASSERT( pv == nullptr ); - CPPUNIT_ASSERT( q.empty() ); - CPPUNIT_ASSERT( check_ic( q.size(), 0 )); - CPPUNIT_ASSERT( v1.nDisposeCount == 4 ); - CPPUNIT_ASSERT( v2.nDisposeCount == 4 ); - CPPUNIT_ASSERT( v3.nDisposeCount == 4 ); - } - - void test_MichaelDeque_HP_default(); - void test_MichaelDeque_HP_default_ic(); - void test_MichaelDeque_HP_default_stat(); - void test_MichaelDeque_HP_base(); - void test_MichaelDeque_HP_member(); - void test_MichaelDeque_HP_base_ic(); - void test_MichaelDeque_HP_member_ic(); - void test_MichaelDeque_HP_base_stat(); - void test_MichaelDeque_HP_member_stat(); - void test_MichaelDeque_HP_base_align(); - void test_MichaelDeque_HP_member_align(); - void test_MichaelDeque_HP_base_noalign(); - void test_MichaelDeque_HP_member_noalign(); - void test_MichaelDeque_PTB_base(); - void test_MichaelDeque_PTB_member(); - void test_MichaelDeque_PTB_base_ic(); - void test_MichaelDeque_PTB_member_ic(); - void test_MichaelDeque_PTB_base_stat(); - void test_MichaelDeque_PTB_member_stat(); - void test_MichaelDeque_PTB_base_align(); - void test_MichaelDeque_PTB_member_align(); - void test_MichaelDeque_PTB_base_noalign(); - void test_MichaelDeque_PTB_member_noalign(); - - CPPUNIT_TEST_SUITE(IntrusiveDequeHeaderTest) - CPPUNIT_TEST( test_MichaelDeque_HP_default); - CPPUNIT_TEST( test_MichaelDeque_HP_default_ic); - CPPUNIT_TEST( test_MichaelDeque_HP_default_stat); - CPPUNIT_TEST( test_MichaelDeque_HP_base); - CPPUNIT_TEST( test_MichaelDeque_HP_member); - CPPUNIT_TEST( test_MichaelDeque_HP_base_ic); - CPPUNIT_TEST( test_MichaelDeque_HP_member_ic); - CPPUNIT_TEST( test_MichaelDeque_HP_base_stat); - CPPUNIT_TEST( test_MichaelDeque_HP_member_stat); - CPPUNIT_TEST( test_MichaelDeque_HP_base_align); - CPPUNIT_TEST( test_MichaelDeque_HP_member_align); - CPPUNIT_TEST( test_MichaelDeque_HP_base_noalign); - CPPUNIT_TEST( test_MichaelDeque_HP_member_noalign); - CPPUNIT_TEST( test_MichaelDeque_PTB_base); - CPPUNIT_TEST( test_MichaelDeque_PTB_member); - CPPUNIT_TEST( test_MichaelDeque_PTB_base_ic); - CPPUNIT_TEST( test_MichaelDeque_PTB_member_ic); - CPPUNIT_TEST( test_MichaelDeque_PTB_base_stat); - CPPUNIT_TEST( test_MichaelDeque_PTB_member_stat); - CPPUNIT_TEST( test_MichaelDeque_PTB_base_align); - CPPUNIT_TEST( test_MichaelDeque_PTB_member_align); - CPPUNIT_TEST( test_MichaelDeque_PTB_base_noalign); - CPPUNIT_TEST( test_MichaelDeque_PTB_member_noalign); - - CPPUNIT_TEST_SUITE_END() - }; - -} // namespace deque diff --git a/tests/test-hdr/deque/hdr_intrusive_michael_deque_hp.cpp b/tests/test-hdr/deque/hdr_intrusive_michael_deque_hp.cpp deleted file mode 100644 index 2524bb88..00000000 --- a/tests/test-hdr/deque/hdr_intrusive_michael_deque_hp.cpp +++ /dev/null @@ -1,166 +0,0 @@ -//$$CDS-header$$ - -#include "hdr_intrusive_deque.h" -#include -#include - -namespace deque { -#define TEST(X) void IntrusiveDequeHeaderTest::test_##X() { test(); } - - namespace { - typedef cds::gc::HP HP; - typedef ci::michael_deque::node node_hp; - - typedef ci::MichaelDeque< HP, - IntrusiveDequeHeaderTest::base_hook_item< node_hp > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - > MichaelDeque_HP_default; - - /// HP + item counter - typedef ci::MichaelDeque< HP, - IntrusiveDequeHeaderTest::base_hook_item< node_hp > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - ,co::item_counter< cds::atomicity::item_counter > - ,co::memory_model< co::v::sequential_consistent > - > MichaelDeque_HP_default_ic; - - /// HP + stat - typedef ci::MichaelDeque< HP, - IntrusiveDequeHeaderTest::base_hook_item< node_hp > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - ,co::stat< ci::michael_deque::stat<> > - > MichaelDeque_HP_default_stat; - - // HP base hook - typedef ci::MichaelDeque< HP, - IntrusiveDequeHeaderTest::base_hook_item< node_hp > - ,ci::opt::hook< - ci::michael_deque::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - > MichaelDeque_HP_base; - - // HP member hook - typedef ci::MichaelDeque< HP, - IntrusiveDequeHeaderTest::member_hook_item< node_hp > - ,ci::opt::hook< - ci::michael_deque::member_hook< - offsetof(IntrusiveDequeHeaderTest::member_hook_item< node_hp >, hMember), - ci::opt::gc - > - > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - > MichaelDeque_HP_member; - - /// HP base hook + item counter - typedef ci::MichaelDeque< HP, - IntrusiveDequeHeaderTest::base_hook_item< node_hp > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::michael_deque::base_hook< ci::opt::gc > - > - ,co::item_counter< cds::atomicity::item_counter > - ,co::memory_model< co::v::relaxed_ordering > - > MichaelDeque_HP_base_ic; - - // HP member hook + item counter - typedef ci::MichaelDeque< HP, - IntrusiveDequeHeaderTest::member_hook_item< node_hp > - ,ci::opt::hook< - ci::michael_deque::member_hook< - offsetof(IntrusiveDequeHeaderTest::member_hook_item< node_hp >, hMember), - ci::opt::gc - > - > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - ,co::item_counter< cds::atomicity::item_counter > - > MichaelDeque_HP_member_ic; - - // HP base hook + stat - typedef ci::MichaelDeque< HP, - IntrusiveDequeHeaderTest::base_hook_item< node_hp > - ,ci::opt::hook< - ci::michael_deque::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - ,co::stat< ci::michael_deque::stat<> > - > MichaelDeque_HP_base_stat; - - // HP member hook + stat - typedef ci::MichaelDeque< HP, - IntrusiveDequeHeaderTest::member_hook_item< node_hp > - ,ci::opt::hook< - ci::michael_deque::member_hook< - offsetof(IntrusiveDequeHeaderTest::member_hook_item< node_hp >, hMember), - ci::opt::gc - > - > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - ,co::stat< ci::michael_deque::stat<> > - > MichaelDeque_HP_member_stat; - - // HP base hook + alignment - typedef ci::MichaelDeque< HP, - IntrusiveDequeHeaderTest::base_hook_item< node_hp > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::michael_deque::base_hook< ci::opt::gc > - > - ,co::alignment< 32 > - > MichaelDeque_HP_base_align; - - // HP member hook + alignment - typedef ci::MichaelDeque< HP, - IntrusiveDequeHeaderTest::member_hook_item< node_hp > - ,ci::opt::hook< - ci::michael_deque::member_hook< - offsetof(IntrusiveDequeHeaderTest::member_hook_item< node_hp >, hMember), - ci::opt::gc - > - > - ,co::alignment< 32 > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - > MichaelDeque_HP_member_align; - - // HP base hook + no alignment - typedef ci::MichaelDeque< HP, - IntrusiveDequeHeaderTest::base_hook_item< node_hp > - ,ci::opt::hook< - ci::michael_deque::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - ,co::alignment< co::no_special_alignment > - > MichaelDeque_HP_base_noalign; - - // HP member hook + no alignment - typedef ci::MichaelDeque< HP, - IntrusiveDequeHeaderTest::member_hook_item< node_hp > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::michael_deque::member_hook< - offsetof(IntrusiveDequeHeaderTest::member_hook_item< node_hp >, hMember), - ci::opt::gc - > - > - ,co::alignment< co::no_special_alignment > - > MichaelDeque_HP_member_noalign; - - } // namespace - - TEST( MichaelDeque_HP_default) - TEST( MichaelDeque_HP_default_ic) - TEST( MichaelDeque_HP_default_stat) - TEST( MichaelDeque_HP_base) - TEST( MichaelDeque_HP_member) - TEST( MichaelDeque_HP_base_ic) - TEST( MichaelDeque_HP_member_ic) - TEST( MichaelDeque_HP_base_stat) - TEST( MichaelDeque_HP_member_stat) - TEST( MichaelDeque_HP_base_align) - TEST( MichaelDeque_HP_member_align) - TEST( MichaelDeque_HP_base_noalign) - TEST( MichaelDeque_HP_member_noalign) - -} // namespace deque - -CPPUNIT_TEST_SUITE_REGISTRATION(deque::IntrusiveDequeHeaderTest); diff --git a/tests/test-hdr/deque/hdr_intrusive_michael_deque_ptb.cpp b/tests/test-hdr/deque/hdr_intrusive_michael_deque_ptb.cpp deleted file mode 100644 index a4fc0895..00000000 --- a/tests/test-hdr/deque/hdr_intrusive_michael_deque_ptb.cpp +++ /dev/null @@ -1,142 +0,0 @@ -//$$CDS-header$$ - -#include "hdr_intrusive_deque.h" -#include -#include - -namespace deque { -#define TEST(X) void IntrusiveDequeHeaderTest::test_##X() { test(); } - - namespace { - typedef cds::gc::PTB PTB; - typedef ci::michael_deque::node node_ptb; - - // PTB base hook - typedef ci::MichaelDeque< PTB, - IntrusiveDequeHeaderTest::base_hook_item< node_ptb > - ,ci::opt::hook< - ci::michael_deque::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - > MichaelDeque_PTB_base; - - // PTB member hook - typedef ci::MichaelDeque< PTB, - IntrusiveDequeHeaderTest::member_hook_item< node_ptb > - ,ci::opt::hook< - ci::michael_deque::member_hook< - offsetof(IntrusiveDequeHeaderTest::member_hook_item< node_ptb >, hMember), - ci::opt::gc - > - > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - > MichaelDeque_PTB_member; - - /// PTB base hook + item counter - typedef ci::MichaelDeque< PTB, - IntrusiveDequeHeaderTest::base_hook_item< node_ptb > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::michael_deque::base_hook< ci::opt::gc > - > - ,co::item_counter< cds::atomicity::item_counter > - ,co::memory_model< co::v::relaxed_ordering > - > MichaelDeque_PTB_base_ic; - - // PTB member hook + item counter - typedef ci::MichaelDeque< PTB, - IntrusiveDequeHeaderTest::member_hook_item< node_ptb > - ,ci::opt::hook< - ci::michael_deque::member_hook< - offsetof(IntrusiveDequeHeaderTest::member_hook_item< node_ptb >, hMember), - ci::opt::gc - > - > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - ,co::item_counter< cds::atomicity::item_counter > - > MichaelDeque_PTB_member_ic; - - // PTB base hook + stat - typedef ci::MichaelDeque< PTB, - IntrusiveDequeHeaderTest::base_hook_item< node_ptb > - ,ci::opt::hook< - ci::michael_deque::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - ,co::stat< ci::michael_deque::stat<> > - > MichaelDeque_PTB_base_stat; - - // PTB member hook + stat - typedef ci::MichaelDeque< PTB, - IntrusiveDequeHeaderTest::member_hook_item< node_ptb > - ,ci::opt::hook< - ci::michael_deque::member_hook< - offsetof(IntrusiveDequeHeaderTest::member_hook_item< node_ptb >, hMember), - ci::opt::gc - > - > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - ,co::stat< ci::michael_deque::stat<> > - > MichaelDeque_PTB_member_stat; - - // PTB base hook + alignment - typedef ci::MichaelDeque< PTB, - IntrusiveDequeHeaderTest::base_hook_item< node_ptb > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::michael_deque::base_hook< ci::opt::gc > - > - ,co::alignment< 32 > - > MichaelDeque_PTB_base_align; - - // PTB member hook + alignment - typedef ci::MichaelDeque< PTB, - IntrusiveDequeHeaderTest::member_hook_item< node_ptb > - ,ci::opt::hook< - ci::michael_deque::member_hook< - offsetof(IntrusiveDequeHeaderTest::member_hook_item< node_ptb >, hMember), - ci::opt::gc - > - > - ,co::alignment< 32 > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - > MichaelDeque_PTB_member_align; - - // PTB base hook + no alignment - typedef ci::MichaelDeque< PTB, - IntrusiveDequeHeaderTest::base_hook_item< node_ptb > - ,ci::opt::hook< - ci::michael_deque::base_hook< ci::opt::gc > - > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - ,co::alignment< co::no_special_alignment > - > MichaelDeque_PTB_base_noalign; - - // PTB member hook + no alignment - typedef ci::MichaelDeque< PTB, - IntrusiveDequeHeaderTest::member_hook_item< node_ptb > - ,ci::opt::disposer< IntrusiveDequeHeaderTest::faked_disposer > - ,ci::opt::hook< - ci::michael_deque::member_hook< - offsetof(IntrusiveDequeHeaderTest::member_hook_item< node_ptb >, hMember), - ci::opt::gc - > - > - ,co::alignment< co::no_special_alignment > - > MichaelDeque_PTB_member_noalign; - } // namespace - - TEST( MichaelDeque_PTB_base) - TEST( MichaelDeque_PTB_member) - TEST( MichaelDeque_PTB_base_ic) - TEST( MichaelDeque_PTB_member_ic) - TEST( MichaelDeque_PTB_base_stat) - TEST( MichaelDeque_PTB_member_stat) - TEST( MichaelDeque_PTB_base_align) - TEST( MichaelDeque_PTB_member_align) - TEST( MichaelDeque_PTB_base_noalign) - TEST( MichaelDeque_PTB_member_noalign) - - -} // namespace deque - diff --git a/tests/test-hdr/deque/hdr_michael_deque_hp.cpp b/tests/test-hdr/deque/hdr_michael_deque_hp.cpp deleted file mode 100644 index 6bd39f5f..00000000 --- a/tests/test-hdr/deque/hdr_michael_deque_hp.cpp +++ /dev/null @@ -1,45 +0,0 @@ -//$$CDS-header$$ - -#include "hdr_deque.h" -#include -#include - -namespace deque { -#define TEST(X) void DequeHeaderTest::test_##X() { test(); } - - namespace cc = cds::container; - namespace co = cds::opt; - - namespace { - typedef cds::gc::HP HP; - typedef deque::DequeHeaderTest::value_type value_type; - - typedef cc::MichaelDeque< HP, value_type > MichaelDeque_HP; - - /// HP + item counter - typedef cc::MichaelDeque< HP, value_type - ,co::item_counter< cds::atomicity::item_counter > - ,co::memory_model< co::v::sequential_consistent > - > MichaelDeque_HP_ic; - - /// HP + stat - typedef cc::MichaelDeque< HP, value_type - ,co::stat< cds::intrusive::michael_deque::stat<> > - > MichaelDeque_HP_stat; - - /// HP + noalign - typedef cc::MichaelDeque< HP, value_type - ,co::alignment< co::no_special_alignment > - ,co::item_counter< cds::atomicity::item_counter > - > MichaelDeque_HP_noalign; - - } // namespace - - TEST( MichaelDeque_HP) - TEST( MichaelDeque_HP_ic) - TEST( MichaelDeque_HP_stat) - TEST( MichaelDeque_HP_noalign) - -} // namespace deque - -CPPUNIT_TEST_SUITE_REGISTRATION(deque::DequeHeaderTest); diff --git a/tests/test-hdr/deque/hdr_michael_deque_ptb.cpp b/tests/test-hdr/deque/hdr_michael_deque_ptb.cpp deleted file mode 100644 index a7ea2579..00000000 --- a/tests/test-hdr/deque/hdr_michael_deque_ptb.cpp +++ /dev/null @@ -1,43 +0,0 @@ -//$$CDS-header$$ - -#include "hdr_deque.h" -#include -#include - -namespace deque { -#define TEST(X) void DequeHeaderTest::test_##X() { test(); } - - namespace cc = cds::container; - namespace co = cds::opt; - - namespace { - typedef cds::gc::PTB PTB; - typedef deque::DequeHeaderTest::value_type value_type; - - typedef cc::MichaelDeque< PTB, value_type > MichaelDeque_PTB; - - /// PTB + item counter - typedef cc::MichaelDeque< PTB, value_type - ,co::item_counter< cds::atomicity::item_counter > - ,co::memory_model< co::v::sequential_consistent > - > MichaelDeque_PTB_ic; - - /// PTB + stat - typedef cc::MichaelDeque< PTB, value_type - ,co::stat< cds::intrusive::michael_deque::stat<> > - > MichaelDeque_PTB_stat; - - /// PTB + noalign - typedef cc::MichaelDeque< PTB, value_type - ,co::alignment< co::no_special_alignment > - ,co::item_counter< cds::atomicity::item_counter > - > MichaelDeque_PTB_noalign; - - } // namespace - - TEST( MichaelDeque_PTB) - TEST( MichaelDeque_PTB_ic) - TEST( MichaelDeque_PTB_stat) - TEST( MichaelDeque_PTB_noalign) - -} // namespace deque diff --git a/tests/unit/print_deque_stat.h b/tests/unit/print_deque_stat.h deleted file mode 100644 index 1c583816..00000000 --- a/tests/unit/print_deque_stat.h +++ /dev/null @@ -1,41 +0,0 @@ -//$$CDS-header$$ - -#ifndef __UNIT_PRINT_DEQUE_STAT_H -#define __UNIT_PRINT_DEQUE_STAT_H - -#include -#include - -namespace std { - - inline ostream& operator <<( ostream& o, cds::intrusive::deque_stat<> const& s ) - { - return o << "\tStatistics:\n" - << "\t\t Push front: " << s.m_PushFrontCount.get() << "\n" - << "\t\t Push back: " << s.m_PushBackCount.get() << "\n" - << "\t\t Pop front: " << s.m_PopFrontCount.get() << "\n" - << "\t\t Pop back: " << s.m_PopBackCount.get() << "\n" - << "\t\tPush front contention: " << s.m_PushFrontContentionCount.get() << "\n" - << "\t\t Push back contention: " << s.m_PushBackContentionCount.get() << "\n" - << "\t\t Pop front contention: " << s.m_PopFrontContentionCount.get() << "\n" - << "\t\t Pop back contention: " << s.m_PopBackContentionCount.get() << "\n" - << "\t\t Pop empty: " << s.m_PopEmptyCount.get() << "\n" -; - } - - inline ostream& operator <<( ostream& o, cds::intrusive::michael_deque::stat<> const& s ) - { - return o << static_cast const&>( s ) - << "\t\t Stabilize front: " << s.m_StabilizeFrontCount.get() << "\n" - << "\t\t Stabilize back: " << s.m_StabilizeBackCount.get() << "\n" -; - } - - inline ostream& operator <<( ostream& o, cds::intrusive::michael_deque::dummy_stat const& ) - { - return o; - } - -} // namespace std - -#endif // #ifndef __UNIT_PRINT_DEQUE_STAT_H diff --git a/tests/unit/queue/intrusive_queue_defs.h b/tests/unit/queue/intrusive_queue_defs.h index 16d72fba..6be614cd 100644 --- a/tests/unit/queue/intrusive_queue_defs.h +++ b/tests/unit/queue/intrusive_queue_defs.h @@ -113,37 +113,6 @@ CPPUNIT_TEST(BasketQueue_PTB_stat) \ CPPUNIT_TEST(BasketQueue_PTB_seqcst) - -// MichaelDeque -#define CDSUNIT_DECLARE_MichaelDeque \ - TEST_CASE(MichaelDequeL_HP, cds::intrusive::michael_deque::node< cds::gc::HP > ) \ - TEST_CASE(MichaelDequeL_HP_ic, cds::intrusive::michael_deque::node< cds::gc::HP > ) \ - TEST_CASE(MichaelDequeL_HP_stat, cds::intrusive::michael_deque::node< cds::gc::HP > ) \ - TEST_CASE(MichaelDequeL_PTB, cds::intrusive::michael_deque::node< cds::gc::PTB > ) \ - TEST_CASE(MichaelDequeL_PTB_ic, cds::intrusive::michael_deque::node< cds::gc::PTB > ) \ - TEST_CASE(MichaelDequeL_PTB_stat, cds::intrusive::michael_deque::node< cds::gc::PTB > ) \ - TEST_CASE(MichaelDequeR_HP, cds::intrusive::michael_deque::node< cds::gc::HP > ) \ - TEST_CASE(MichaelDequeR_HP_ic, cds::intrusive::michael_deque::node< cds::gc::HP > ) \ - TEST_CASE(MichaelDequeR_HP_stat, cds::intrusive::michael_deque::node< cds::gc::HP > ) \ - TEST_CASE(MichaelDequeR_PTB, cds::intrusive::michael_deque::node< cds::gc::PTB > ) \ - TEST_CASE(MichaelDequeR_PTB_ic, cds::intrusive::michael_deque::node< cds::gc::PTB > ) \ - TEST_CASE(MichaelDequeR_PTB_stat, cds::intrusive::michael_deque::node< cds::gc::PTB > ) - -#define CDSUNIT_TEST_MichaelDeque \ - CPPUNIT_TEST(MichaelDequeL_HP) \ - CPPUNIT_TEST(MichaelDequeL_HP_ic) \ - CPPUNIT_TEST(MichaelDequeL_HP_stat) \ - CPPUNIT_TEST(MichaelDequeL_PTB) \ - CPPUNIT_TEST(MichaelDequeL_PTB_ic) \ - CPPUNIT_TEST(MichaelDequeL_PTB_stat) \ - CPPUNIT_TEST(MichaelDequeR_HP) \ - CPPUNIT_TEST(MichaelDequeR_HP_ic) \ - CPPUNIT_TEST(MichaelDequeR_HP_stat) \ - CPPUNIT_TEST(MichaelDequeR_PTB) \ - CPPUNIT_TEST(MichaelDequeR_PTB_ic) \ - CPPUNIT_TEST(MichaelDequeR_PTB_stat) - - // TsigasCycleQueue #define CDSUNIT_DECLARE_TsigasCycleQueue \ TEST_BOUNDED(TsigasCycleQueue_dyn) \ diff --git a/tests/unit/queue/intrusive_queue_type.h b/tests/unit/queue/intrusive_queue_type.h index 7e9f65ac..14cc4fc7 100644 --- a/tests/unit/queue/intrusive_queue_type.h +++ b/tests/unit/queue/intrusive_queue_type.h @@ -10,7 +10,6 @@ #include #include #include -#include #include #include @@ -19,7 +18,6 @@ #include -#include "print_deque_stat.h" #include "print_segmentedqueue_stat.h" namespace queue { @@ -27,70 +25,6 @@ namespace queue { namespace details { struct empty_stat {}; - // MichaelDeque, push right/pop left - template - class MichaelDequeR: public cds::intrusive::MichaelDeque< GC, T, CDS_OPTIONS10> - { - typedef cds::intrusive::MichaelDeque< GC, T, CDS_OPTIONS10> base_class; - public: - MichaelDequeR( size_t nMaxItemCount ) - : base_class( (unsigned int) nMaxItemCount, 4 ) - {} - MichaelDequeR() - : base_class( 64 * 1024, 4 ) - {} - - bool push( T& v ) - { - return base_class::push_back( v ); - } - bool enqueue( T& v ) - { - return push( v ); - } - - T * pop() - { - return base_class::pop_front(); - } - T * deque() - { - return pop(); - } - }; - - // MichaelDeque, push left/pop right - template - class MichaelDequeL: public cds::intrusive::MichaelDeque< GC, T, CDS_OPTIONS10> - { - typedef cds::intrusive::MichaelDeque< GC, T, CDS_OPTIONS10> base_class; - public: - MichaelDequeL( size_t nMaxItemCount ) - : base_class( (unsigned int) nMaxItemCount, 4 ) - {} - MichaelDequeL() - : base_class( 64 * 1024, 4 ) - {} - - bool push( T& v ) - { - return base_class::push_front( v ); - } - bool enqueue( T& v ) - { - return push( v ); - } - - T * pop() - { - return base_class::pop_back(); - } - T * deque() - { - return pop(); - } - }; - template class BoostSList { @@ -410,57 +344,6 @@ namespace queue { } }; - - // MichaelDeque - typedef details::MichaelDequeR< cds::gc::HP, T - ,cds::intrusive::opt::hook< cds::intrusive::michael_deque::base_hook< cds::opt::gc< cds::gc::HP > > > - > MichaelDequeR_HP; - typedef details::MichaelDequeR< cds::gc::HP, T - ,cds::intrusive::opt::hook< cds::intrusive::michael_deque::base_hook< cds::opt::gc< cds::gc::HP > > > - ,cds::opt::item_counter< cds::atomicity::item_counter > - > MichaelDequeR_HP_ic; - typedef details::MichaelDequeR< cds::gc::HP, T - ,cds::intrusive::opt::hook< cds::intrusive::michael_deque::base_hook< cds::opt::gc< cds::gc::HP > > > - ,cds::opt::stat< cds::intrusive::michael_deque::stat<> > - > MichaelDequeR_HP_stat; - - typedef details::MichaelDequeR< cds::gc::PTB, T - ,cds::intrusive::opt::hook< cds::intrusive::michael_deque::base_hook< cds::opt::gc< cds::gc::PTB > > > - > MichaelDequeR_PTB; - typedef details::MichaelDequeR< cds::gc::PTB, T - ,cds::intrusive::opt::hook< cds::intrusive::michael_deque::base_hook< cds::opt::gc< cds::gc::PTB > > > - ,cds::opt::item_counter< cds::atomicity::item_counter > - > MichaelDequeR_PTB_ic; - typedef details::MichaelDequeR< cds::gc::PTB, T - ,cds::intrusive::opt::hook< cds::intrusive::michael_deque::base_hook< cds::opt::gc< cds::gc::PTB > > > - ,cds::opt::stat< cds::intrusive::michael_deque::stat<> > - > MichaelDequeR_PTB_stat; - - typedef details::MichaelDequeL< cds::gc::HP, T - ,cds::intrusive::opt::hook< cds::intrusive::michael_deque::base_hook< cds::opt::gc< cds::gc::HP > > > - > MichaelDequeL_HP; - typedef details::MichaelDequeL< cds::gc::HP, T - ,cds::intrusive::opt::hook< cds::intrusive::michael_deque::base_hook< cds::opt::gc< cds::gc::HP > > > - ,cds::opt::item_counter< cds::atomicity::item_counter > - > MichaelDequeL_HP_ic; - typedef details::MichaelDequeL< cds::gc::HP, T - ,cds::intrusive::opt::hook< cds::intrusive::michael_deque::base_hook< cds::opt::gc< cds::gc::HP > > > - ,cds::opt::stat< cds::intrusive::michael_deque::stat<> > - > MichaelDequeL_HP_stat; - - - typedef details::MichaelDequeL< cds::gc::PTB, T - ,cds::intrusive::opt::hook< cds::intrusive::michael_deque::base_hook< cds::opt::gc< cds::gc::PTB > > > - > MichaelDequeL_PTB; - typedef details::MichaelDequeL< cds::gc::PTB, T - ,cds::intrusive::opt::hook< cds::intrusive::michael_deque::base_hook< cds::opt::gc< cds::gc::PTB > > > - ,cds::opt::item_counter< cds::atomicity::item_counter > - > MichaelDequeL_PTB_ic; - typedef details::MichaelDequeL< cds::gc::PTB, T - ,cds::intrusive::opt::hook< cds::intrusive::michael_deque::base_hook< cds::opt::gc< cds::gc::PTB > > > - ,cds::opt::stat< cds::intrusive::michael_deque::stat<> > - > MichaelDequeL_PTB_stat; - // 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 > > > diff --git a/tests/unit/queue/queue_defs.h b/tests/unit/queue/queue_defs.h index 34d24d06..ef5bf23a 100644 --- a/tests/unit/queue/queue_defs.h +++ b/tests/unit/queue/queue_defs.h @@ -207,45 +207,6 @@ CPPUNIT_TEST(RWQueue_Spin_ic) \ CPPUNIT_TEST(RWQueue_Spin_stat) - -// MichalDeque -#define CDSUNIT_DECLARE_MichaelDeque( ITEM_TYPE ) \ - TEST_BOUNDED(MichaelDequeL_HP, ITEM_TYPE) \ - TEST_BOUNDED(MichaelDequeL_HP_ic, ITEM_TYPE) \ - TEST_BOUNDED(MichaelDequeL_HP_michaelAlloc, ITEM_TYPE) \ - TEST_BOUNDED(MichaelDequeL_HP_stat, ITEM_TYPE) \ - TEST_BOUNDED(MichaelDequeL_PTB, ITEM_TYPE) \ - TEST_BOUNDED(MichaelDequeL_PTB_ic, ITEM_TYPE) \ - TEST_BOUNDED(MichaelDequeL_PTB_michaelAlloc, ITEM_TYPE) \ - TEST_BOUNDED(MichaelDequeL_PTB_stat, ITEM_TYPE) \ - TEST_BOUNDED(MichaelDequeR_HP, ITEM_TYPE) \ - TEST_BOUNDED(MichaelDequeR_HP_ic, ITEM_TYPE) \ - TEST_BOUNDED(MichaelDequeR_HP_michaelAlloc, ITEM_TYPE) \ - TEST_BOUNDED(MichaelDequeR_HP_stat, ITEM_TYPE) \ - TEST_BOUNDED(MichaelDequeR_PTB, ITEM_TYPE) \ - TEST_BOUNDED(MichaelDequeR_PTB_ic, ITEM_TYPE) \ - TEST_BOUNDED(MichaelDequeR_PTB_michaelAlloc, ITEM_TYPE) \ - TEST_BOUNDED(MichaelDequeR_PTB_stat, ITEM_TYPE) - -#define CDSUNIT_TEST_MichaelDeque \ - CPPUNIT_TEST(MichaelDequeL_HP ) \ - CPPUNIT_TEST(MichaelDequeL_HP_ic ) \ - CPPUNIT_TEST(MichaelDequeL_HP_michaelAlloc ) \ - CPPUNIT_TEST(MichaelDequeL_HP_stat ) \ - CPPUNIT_TEST(MichaelDequeL_PTB ) \ - CPPUNIT_TEST(MichaelDequeL_PTB_ic ) \ - CPPUNIT_TEST(MichaelDequeL_PTB_michaelAlloc ) \ - CPPUNIT_TEST(MichaelDequeL_PTB_stat ) \ - CPPUNIT_TEST(MichaelDequeR_HP ) \ - CPPUNIT_TEST(MichaelDequeR_HP_ic ) \ - CPPUNIT_TEST(MichaelDequeR_HP_michaelAlloc ) \ - CPPUNIT_TEST(MichaelDequeR_HP_stat ) \ - CPPUNIT_TEST(MichaelDequeR_PTB ) \ - CPPUNIT_TEST(MichaelDequeR_PTB_ic ) \ - CPPUNIT_TEST(MichaelDequeR_PTB_michaelAlloc ) \ - CPPUNIT_TEST(MichaelDequeR_PTB_stat ) - - // TsigasCycleQueue #define CDSUNIT_DECLARE_TsigasCysleQueue( ITEM_TYPE ) \ TEST_BOUNDED(TsigasCycleQueue_dyn, ITEM_TYPE) \ diff --git a/tests/unit/queue/queue_type.h b/tests/unit/queue/queue_type.h index 16dbc16d..7004675d 100644 --- a/tests/unit/queue/queue_type.h +++ b/tests/unit/queue/queue_type.h @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -22,78 +21,12 @@ #include "queue/std_queue.h" #include "lock/win32_lock.h" #include "michael_alloc.h" -#include "print_deque_stat.h" #include "print_segmentedqueue_stat.h" #include namespace queue { - namespace details { - // MichaelDeque, push right/pop left - template - class MichaelDequeR: public cds::container::MichaelDeque< GC, T, CDS_OPTIONS7> - { - typedef cds::container::MichaelDeque< GC, T, CDS_OPTIONS7> base_class; - public: - MichaelDequeR( size_t nMaxItemCount ) - : base_class( (unsigned int) nMaxItemCount, 4 ) - {} - MichaelDequeR() - : base_class( 64 * 1024, 4 ) - {} - - bool push( T const& v ) - { - return base_class::push_back( v ); - } - bool enqueue( T const& v ) - { - return push( v ); - } - - bool pop( T& v ) - { - return base_class::pop_front( v ); - } - bool deque( T& v ) - { - return pop(v); - } - }; - - // MichaelDeque, push left/pop right - template - class MichaelDequeL: public cds::container::MichaelDeque< GC, T, CDS_OPTIONS7> - { - typedef cds::container::MichaelDeque< GC, T, CDS_OPTIONS7> base_class; - public: - MichaelDequeL( size_t nMaxItemCount ) - : base_class( (unsigned int) nMaxItemCount, 4 ) - {} - MichaelDequeL() - : base_class( 64 * 1024, 4 ) - {} - - bool push( T const& v ) - { - return base_class::push_front( v ); - } - bool enqueue( T const& v ) - { - return push( v ); - } - - bool pop( T& v ) - { - return base_class::pop_back( v ); - } - bool deque( T& v ) - { - return pop(v); - } - }; - template > class FCDequeL: public cds::container::FCDeque { @@ -524,53 +457,6 @@ namespace queue { } }; - - // MichaelDeque - typedef details::MichaelDequeR< cds::gc::HP, Value > MichaelDequeR_HP; - typedef details::MichaelDequeR< cds::gc::HP, Value - ,cds::opt::item_counter< cds::atomicity::item_counter > - > MichaelDequeR_HP_ic; - typedef details::MichaelDequeR< cds::gc::HP, Value - ,cds::opt::allocator< memory::MichaelAllocator > - > MichaelDequeR_HP_michaelAlloc; - typedef details::MichaelDequeR< cds::gc::HP, Value - ,cds::opt::stat< cds::intrusive::michael_deque::stat<> > - > MichaelDequeR_HP_stat; - - typedef details::MichaelDequeR< cds::gc::PTB, Value > MichaelDequeR_PTB; - typedef details::MichaelDequeR< cds::gc::PTB, Value - ,cds::opt::item_counter< cds::atomicity::item_counter > - > MichaelDequeR_PTB_ic; - typedef details::MichaelDequeR< cds::gc::PTB, Value - ,cds::opt::allocator< memory::MichaelAllocator > - > MichaelDequeR_PTB_michaelAlloc; - typedef details::MichaelDequeR< cds::gc::PTB, Value - ,cds::opt::stat< cds::intrusive::michael_deque::stat<> > - > MichaelDequeR_PTB_stat; - - typedef details::MichaelDequeL< cds::gc::HP, Value > MichaelDequeL_HP; - typedef details::MichaelDequeL< cds::gc::HP, Value - ,cds::opt::item_counter< cds::atomicity::item_counter > - > MichaelDequeL_HP_ic; - typedef details::MichaelDequeL< cds::gc::HP, Value - ,cds::opt::allocator< memory::MichaelAllocator > - > MichaelDequeL_HP_michaelAlloc; - typedef details::MichaelDequeL< cds::gc::HP, Value - ,cds::opt::stat< cds::intrusive::michael_deque::stat<> > - > MichaelDequeL_HP_stat; - - - typedef details::MichaelDequeL< cds::gc::PTB, Value > MichaelDequeL_PTB; - typedef details::MichaelDequeL< cds::gc::PTB, Value - ,cds::opt::item_counter< cds::atomicity::item_counter > - > MichaelDequeL_PTB_ic; - typedef details::MichaelDequeL< cds::gc::PTB, Value - ,cds::opt::allocator< memory::MichaelAllocator > - > MichaelDequeL_PTB_michaelAlloc; - typedef details::MichaelDequeL< cds::gc::PTB, Value - ,cds::opt::stat< cds::intrusive::michael_deque::stat<> > - > MichaelDequeL_PTB_stat; - // BasketQueue typedef cds::container::BasketQueue< cds::gc::HP , Value diff --git a/tests/unit/stack/stack_intrusive_pushpop.cpp b/tests/unit/stack/stack_intrusive_pushpop.cpp index ec6039e5..c94498c6 100644 --- a/tests/unit/stack/stack_intrusive_pushpop.cpp +++ b/tests/unit/stack/stack_intrusive_pushpop.cpp @@ -2,7 +2,6 @@ #include "cppunit/thread.h" #include "stack/intrusive_stack_type.h" -#include "print_deque_stat.h" // Multi-threaded stack test for push/pop operation namespace istack { diff --git a/tests/unit/stack/stack_push.cpp b/tests/unit/stack/stack_push.cpp index f0ccc13a..04dffd4f 100644 --- a/tests/unit/stack/stack_push.cpp +++ b/tests/unit/stack/stack_push.cpp @@ -2,7 +2,6 @@ #include "cppunit/thread.h" #include "stack/stack_type.h" -#include "print_deque_stat.h" // Multi-threaded stack test for push operation namespace stack { diff --git a/tests/unit/stack/stack_pushpop.cpp b/tests/unit/stack/stack_pushpop.cpp index 7d1f8e66..d37f5262 100644 --- a/tests/unit/stack/stack_pushpop.cpp +++ b/tests/unit/stack/stack_pushpop.cpp @@ -2,7 +2,6 @@ #include "cppunit/thread.h" #include "stack/stack_type.h" -#include "print_deque_stat.h" // Multi-threaded stack test for push/pop operation namespace stack { -- 2.34.1