From 4384d73845236b4b9eaf35e4e79e0a1e1ad2f081 Mon Sep 17 00:00:00 2001 From: NikitaKomp Date: Thu, 31 Jan 2019 23:30:06 +0300 Subject: [PATCH 01/26] Replacing Competition with Cooperation to Achieve Scalable Lock-Free FIFO Queues --- cds/container/speculative_pairing_queue.h | 428 +++++++++++ cds/intrusive/details/sp_queue_base.h | 204 ++++++ cds/intrusive/speculative_pairing_queue.h | 671 ++++++++++++++++++ test/stress/queue/CMakeLists.txt | 13 +- test/stress/queue/intrusive_push_pop.cpp | 48 +- test/stress/queue/intrusive_queue_type.h | 92 ++- test/stress/queue/pop.cpp | 43 +- test/stress/queue/print_stat.h | 50 +- test/stress/queue/push.cpp | 47 +- test/stress/queue/push_pop.cpp | 35 +- test/stress/queue/queue_type.h | 71 +- test/stress/queue/random.cpp | 34 +- test/stress/queue/spsc_buffer.cpp | 37 +- test/unit/queue/CMakeLists.txt | 6 +- ...ntrusive_speculative_pairing_queue_dhp.cpp | 179 +++++ ...intrusive_speculative_pairing_queue_hp.cpp | 200 ++++++ .../queue/speculative_pairing_queue_dhp.cpp | 140 ++++ .../queue/speculative_pairing_queue_hp.cpp | 140 ++++ ...test_intrusive_speculative_pairing_queue.h | 201 ++++++ 19 files changed, 2589 insertions(+), 50 deletions(-) create mode 100644 cds/container/speculative_pairing_queue.h create mode 100644 cds/intrusive/details/sp_queue_base.h create mode 100644 cds/intrusive/speculative_pairing_queue.h create mode 100644 test/unit/queue/intrusive_speculative_pairing_queue_dhp.cpp create mode 100644 test/unit/queue/intrusive_speculative_pairing_queue_hp.cpp create mode 100644 test/unit/queue/speculative_pairing_queue_dhp.cpp create mode 100644 test/unit/queue/speculative_pairing_queue_hp.cpp create mode 100644 test/unit/queue/test_intrusive_speculative_pairing_queue.h diff --git a/cds/container/speculative_pairing_queue.h b/cds/container/speculative_pairing_queue.h new file mode 100644 index 000000000..e6bbc1386 --- /dev/null +++ b/cds/container/speculative_pairing_queue.h @@ -0,0 +1,428 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CDSLIB_CONTAINER_SPECULATIVE_PAIRING_QUEUE_H +#define CDSLIB_CONTAINER_SPECULATIVE_PAIRING_QUEUE_H + +#include +#include +#include + +namespace cds { namespace container { + + /// MSQueue related definitions + /** @ingroup cds_nonintrusive_helper + */ + namespace speculative_pairing_queue { + /// Internal statistics + template ::counter_type > + using stat = cds::intrusive::speculative_pairing_queue::stat< Counter >; + + /// Dummy internal statistics + typedef cds::intrusive::speculative_pairing_queue::empty_stat empty_stat; + + /// MSQueue default type traits + struct traits + { + /// Node allocator + typedef CDS_DEFAULT_ALLOCATOR allocator; + + /// Back-off strategy + typedef cds::backoff::empty back_off; + + /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter to enable item counting + typedef atomicity::empty_item_counter item_counter; + + /// Internal statistics (by default, disabled) + /** + Possible option value are: \p msqueue::stat, \p msqueue::empty_stat (the default), + user-provided class that supports \p %msqueue::stat interface. + */ + typedef speculative_pairing_queue::empty_stat stat; + + /// C++ memory ordering model + /** + Can be \p opt::v::relaxed_ordering (relaxed memory model, the default) + or \p opt::v::sequential_consistent (sequentially consisnent memory model). + */ + typedef opt::v::relaxed_ordering memory_model; + + /// Padding for internal critical atomic data. Default is \p opt::cache_line_padding + enum { padding = opt::cache_line_padding }; + }; + + /// Metafunction converting option list to \p msqueue::traits + /** + Supported \p Options are: + - \p opt::allocator - allocator (like \p std::allocator) used for allocating queue nodes. Default is \ref CDS_DEFAULT_ALLOCATOR + - \p opt::back_off - back-off strategy used, default is \p cds::backoff::empty. + - \p opt::item_counter - the type of item counting feature. Default is \p cds::atomicity::empty_item_counter (item counting disabled) + To enable item counting use \p cds::atomicity::item_counter + - \p opt::stat - the type to gather internal statistics. + Possible statistics types are: \p msqueue::stat, \p msqueue::empty_stat, user-provided class that supports \p %msqueue::stat interface. + Default is \p %msqueue::empty_stat. + - \p opt::padding - padding for internal critical atomic data. Default is \p opt::cache_line_padding + - \p opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default) + or \p opt::v::sequential_consistent (sequentially consisnent memory model). + + Example: declare \p %MSQueue with item counting and internal statistics + \code + typedef cds::container::MSQueue< cds::gc::HP, Foo, + typename cds::container::msqueue::make_traits< + cds::opt::item_counter< cds::atomicity::item_counter >, + cds::opt::stat< cds::container::msqueue::stat<> > + >::type + > myQueue; + \endcode + */ + template + struct make_traits { +# ifdef CDS_DOXYGEN_INVOKED + typedef implementation_defined type; ///< Metafunction result +# else + typedef typename cds::opt::make_options< + typename cds::opt::find_type_traits< traits, Options... >::type + , Options... + >::type type; +# endif + }; + } // namespace msqueue + + //@cond + namespace details { + template + struct make_spqueue + { + typedef GC gc; + typedef T value_type; + typedef Traits traits; + + struct node_type : public intrusive::sp_queue::node< gc > + { + value_type m_value; + + node_type( value_type const& val ) + : m_value( val ) + {} + + template + node_type( Args&&... args ) + : m_value( std::forward( args )... ) + {} + }; + + typedef typename traits::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 ); + } + }; + + struct intrusive_traits : public traits + { + typedef cds::intrusive::speculative_pairing_queue::base_hook< cds::opt::gc > hook; + typedef node_deallocator disposer; + static constexpr const cds::intrusive::opt::link_check_type link_checker = cds::intrusive::speculative_pairing_queue::traits::link_checker; + }; + + typedef intrusive::SPQueue< gc, node_type, intrusive_traits > type; + }; + } + //@endcond + + /// Michael & Scott lock-free queue + /** @ingroup cds_nonintrusive_queue + It is non-intrusive version of Michael & Scott's queue algorithm based on intrusive implementation + \p cds::intrusive::MSQueue. + + Template arguments: + - \p GC - garbage collector type: \p gc::HP, \p gc::DHP + - \p T is a type stored in the queue. + - \p Traits - queue traits, default is \p msqueue::traits. You can use \p msqueue::make_traits + metafunction to make your traits or just derive your traits from \p %msqueue::traits: + \code + struct myTraits: public cds::container::msqueue::traits { + typedef cds::intrusive::msqueue::stat<> stat; + typedef cds::atomicity::item_counter item_counter; + }; + typedef cds::container::MSQueue< cds::gc::HP, Foo, myTraits > myQueue; + + // Equivalent make_traits example: + typedef cds::container::MSQueue< cds::gc::HP, Foo, + typename cds::container::msqueue::make_traits< + cds::opt::stat< cds::container::msqueue::stat<> >, + cds::opt::item_counter< cds::atomicity::item_counter > + >::type + > myQueue; + \endcode + */ + template + class SPQueue: +#ifdef CDS_DOXYGEN_INVOKED + private intrusive::SPQueue< GC, cds::intrusive::speculative_pairing_queue::node< T >, Traits > +#else + private details::make_spqueue< GC, T, Traits >::type +#endif + { + //@cond + typedef details::make_spqueue< GC, T, Traits > maker; + typedef typename maker::type base_class; + //@endcond + + public: + /// Rebind template arguments + template + struct rebind { + typedef SPQueue< GC2, T2, Traits2> other ; ///< Rebinding result + }; + + public: + typedef T value_type; ///< Value type stored in the queue + typedef Traits traits; ///< Queue traits + + typedef typename base_class::gc gc; ///< Garbage collector used + typedef typename base_class::back_off back_off; ///< Back-off strategy used + typedef typename maker::allocator_type allocator_type; ///< Allocator type used for allocate/deallocate the nodes + typedef typename base_class::item_counter item_counter; ///< Item counting policy used + typedef typename base_class::stat stat; ///< Internal statistics policy used + typedef typename base_class::memory_model memory_model; ///< Memory ordering. See cds::opt::memory_model option + + static constexpr const size_t c_nHazardPtrCount = base_class::c_nHazardPtrCount; ///< Count of hazard pointer required for the algorithm + + protected: + //@cond + typedef typename maker::node_type node_type; ///< queue node type (derived from \p intrusive::msqueue::node) + + typedef typename maker::cxx_allocator cxx_allocator; + typedef typename maker::node_deallocator node_deallocator; // deallocate node + typedef typename base_class::node_traits node_traits; + //@endcond + + protected: + ///@cond + static node_type * alloc_node() + { + return cxx_allocator().New(); + } + static node_type * alloc_node( value_type const& val ) + { + return cxx_allocator().New( val ); + } + template + static node_type * alloc_node_move( Args&&... args ) + { + return cxx_allocator().MoveNew( std::forward( args )... ); + } + 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; + //@endcond + + public: + /// Initializes empty queue + SPQueue() + {} + + /// Destructor clears the queue + ~SPQueue() + {} + + /// Enqueues \p val value into the queue. + /** + The function makes queue node in dynamic memory calling copy constructor for \p val + and then it calls \p intrusive::MSQueue::enqueue. + Returns \p true if success, \p false otherwise. + */ + bool enqueue( value_type const& val ) + { + scoped_node_ptr p( alloc_node(val)); + if ( base_class::enqueue( *p )) { + p.release(); + return true; + } + return false; + } + + /// Enqueues \p val in the queue, move semantics + bool enqueue( value_type&& val ) + { + scoped_node_ptr p( alloc_node_move( std::move( val ))); + if ( base_class::enqueue( *p )) { + p.release(); + return true; + } + return false; + } + + /// Enqueues data to the queue using a functor + /** + \p Func is a functor called to create node. + The functor \p f takes one argument - a reference to a new node of type \ref value_type : + \code + cds::container::MSQueue< cds::gc::HP, Foo > myQueue; + Bar bar; + myQueue.enqueue_with( [&bar]( Foo& dest ) { dest = bar; } ); + \endcode + */ + template + bool enqueue_with( Func f ) + { + scoped_node_ptr p( alloc_node()); + f( p->m_value ); + if ( base_class::enqueue( *p )) { + p.release(); + return true; + } + return false; + } + + /// Enqueues data of type \ref value_type constructed from std::forward(args)... + template + bool emplace( Args&&... args ) + { + scoped_node_ptr p( alloc_node_move( std::forward( args )... )); + if ( base_class::enqueue( *p )) { + p.release(); + return true; + } + return false; + } + + /// Synonym for \p enqueue() function + bool push( value_type const& val ) + { + return enqueue( val ); + } + + /// Synonym for \p enqueue() function + bool push( value_type&& val ) + { + return enqueue( std::move( val )); + } + + /// Synonym for \p enqueue_with() function + template + bool push_with( Func f ) + { + return enqueue_with( f ); + } + + /// Dequeues a value from the queue + /** + If queue is not empty, the function returns \p true, \p dest contains copy of + dequeued value. The assignment operator for type \ref value_type is invoked. + If queue is empty, the function returns \p false, \p dest is unchanged. + */ + bool dequeue( value_type& dest ) + { + return dequeue_with( [&dest]( value_type& src ) { dest = std::move( src );}); + } + + /// Dequeues a value using a functor + /** + \p Func is a functor called to copy dequeued value. + The functor takes one argument - a reference to removed node: + \code + cds:container::MSQueue< cds::gc::HP, Foo > myQueue; + Bar bar; + myQueue.dequeue_with( [&bar]( Foo& src ) { bar = std::move( src );}); + \endcode + The functor is called only if the queue is not empty. + */ + template + bool dequeue_with( Func f ) + { + node_type* p = base_class::dequeue(); + if ( p) { + f( p->m_value ); + return true; + } + return false; + } + + /// Synonym for \p dequeue() function + bool pop( value_type& dest ) + { + return dequeue( dest ); + } + + /// Synonym for \p dequeue_with() function + template + bool pop_with( Func f ) + { + return dequeue_with( f ); + } + + /// Clear the queue + /** + The function repeatedly calls \ref dequeue until it returns \p nullptr. + */ + void clear() + { + base_class::clear(); + } + + /// Checks if the queue is empty + bool empty() const + { + return base_class::empty(); + } + + /// Returns queue's item count (see \ref intrusive::MSQueue::size for explanation) + /** \copydetails cds::intrusive::MSQueue::size() + */ + size_t size() const + { + return base_class::size(); + } + + /// Returns reference to internal statistics + const stat& statistics() const + { + return base_class::statistics(); + } + }; + +}} // namespace cds::container + +#endif // #ifndef CDSLIB_CONTAINER_MSQUEUE_H diff --git a/cds/intrusive/details/sp_queue_base.h b/cds/intrusive/details/sp_queue_base.h new file mode 100644 index 000000000..e53627d8c --- /dev/null +++ b/cds/intrusive/details/sp_queue_base.h @@ -0,0 +1,204 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CDSLIB_INTRUSIVE_DETAILS_SP_QUEUE_BASE_H +#define CDSLIB_INTRUSIVE_DETAILS_SP_QUEUE_BASE_H + +#include +#include +#include +#include + +namespace cds { namespace intrusive { + + /// Definitions common for single-linked data structures + /** @ingroup cds_intrusive_helper + */ + namespace sp_queue { + + /// Container's node + /** + Template parameters: + - GC - garbage collector used + - Tag - a tag used to distinguish between different implementation + */ + + template + struct node { + typedef GC gc ; ///< Garbage collector + typedef Tag tag ; ///< tag + + typedef typename gc::template atomic_ref atomic_node_ptr; ///< atomic pointer + typedef typename gc::template atomic_type atomic_int; + + /// Rebind node for other template parameters + template + struct rebind { + typedef node other ; ///< Rebinding result + }; + + atomic_node_ptr m_pNext ; ///< pointer to the next node in the container + + atomic_int m_nVer; + bool m_removed = false; + + node() noexcept + { + m_pNext.store( nullptr, atomics::memory_order_release ); + m_nVer.store(0, atomics::memory_order_release); + } + + }; + + + //@cond + struct default_hook { + typedef cds::gc::default_gc gc; + typedef opt::none tag; + }; + //@endcond + + //@cond + template < typename HookType, typename... Options> + struct hook + { + typedef typename opt::make_options< default_hook, Options...>::type options; + typedef typename options::gc gc; + typedef typename options::tag tag; + typedef node node_type; + typedef HookType hook_type; + }; + //@endcond + + /// Base hook + /** + \p Options are: + - opt::gc - garbage collector used. + - opt::tag - tag + */ + template < typename... Options > + struct base_hook: public hook< opt::base_hook_tag, Options... > + {}; + + /// Member hook + /** + \p MemberOffset defines offset in bytes of \ref node member into your structure. + Use \p offsetof macro to define \p MemberOffset + + \p Options are: + - opt::gc - garbage collector used. + - opt::tag - tag + */ + template < size_t MemberOffset, typename... Options > + struct member_hook: public hook< opt::member_hook_tag, Options... > + { + //@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 + */ + template + struct traits_hook: public hook< opt::traits_hook_tag, Options... > + { + //@cond + typedef NodeTraits node_traits; + //@endcond + }; + + /// Check link + template + struct link_checker { + //@cond + typedef Node node_type; + //@endcond + + /// Checks if the link field of node \p pNode is \p nullptr + /** + An asserting is generated if \p pNode link field is not \p nullptr + */ + static void is_empty( const node_type * pNode ) + { + assert( pNode->m_pNext.load( atomics::memory_order_relaxed ) == nullptr ); + CDS_UNUSED( pNode ); + } + }; + + //@cond + template + struct link_checker_selector; + + template + struct link_checker_selector< GC, Node, opt::never_check_link > + { + typedef intrusive::opt::v::empty_link_checker type; + }; + + template + struct link_checker_selector< GC, Node, opt::debug_check_link > + { +# ifdef _DEBUG + typedef link_checker type; +# else + typedef intrusive::opt::v::empty_link_checker type; +# endif + }; + + template + struct link_checker_selector< GC, Node, opt::always_check_link > + { + typedef link_checker type; + }; + //@endcond + + /// Metafunction for selecting appropriate link checking policy + template < typename Node, opt::link_check_type LinkType > + struct get_link_checker + { + //@cond + typedef typename link_checker_selector< typename Node::gc, Node, LinkType>::type type; + //@endcond + }; + + } // namespace single_link + +}} // namespace cds::intrusive + + + +#endif // #ifndef CDSLIB_INTRUSIVE_DETAILS_SINGLE_LINK_STRUCT_H diff --git a/cds/intrusive/speculative_pairing_queue.h b/cds/intrusive/speculative_pairing_queue.h new file mode 100644 index 000000000..f9d1bc246 --- /dev/null +++ b/cds/intrusive/speculative_pairing_queue.h @@ -0,0 +1,671 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CDSLIB_INTRUSIVE_SPECULATIVE_PAIRING_QUEUE_H +#define CDSLIB_INTRUSIVE_SPECULATIVE_PAIRING_QUEUE_H + +#include +#include +#include +#include +#include +#include + +//#include +//#include +//#include +//#include + +#include +#include +#include + +namespace cds { namespace intrusive { + + /// MSPriorityQueue related definitions + /** @ingroup cds_intrusive_helper + */ + namespace speculative_pairing_queue { + //@cond + /// Slot type + template < class GC, typename Tag = opt::none> + using node = cds::intrusive::sp_queue::node< GC, Tag >; + + template < typename... Options > + using base_hook = cds::intrusive::sp_queue::base_hook< Options...>; + + template + using traits_hook = cds::intrusive::sp_queue::traits_hook< NodeTraits, Options... >; + + template < size_t MemberOffset, typename... Options > + using member_hook = cds::intrusive::sp_queue::member_hook< MemberOffset, Options... >; + + /// MSPriorityQueue statistics + template + struct stat { + typedef Counter counter_type ; ///< Event counter type + + counter_type m_nEnqueCount; ///< Count of success enque operation + counter_type m_nQueueCreatingCount; ///< Count of ccd reating Queue on enque + counter_type m_nRepeatEnqueCount; ///< Count of repeat iteration + + counter_type m_nDequeCount; ///< Count of success deque operation + counter_type m_nReturnEmptyInvalid; ///< Count of EMPTY returning because of invalid queue + counter_type m_nClosingQueue; ///< Count of closing queue(made it invalid) + + //@cond + void onEnqueSuccess() { ++m_nEnqueCount ;} + void onDequeSuccess() { ++m_nDequeCount ;} + + void onQueueCreate() { ++m_nQueueCreatingCount ;} + void onRepeatEnque() { ++m_nRepeatEnqueCount ;} + + void onReturnEmpty() { ++m_nReturnEmptyInvalid ;} + void onCloseQueue() { ++m_nClosingQueue ;} + //@endcond + + //@cond + /*void reset() + { + m_EnqueueCount.reset(); + m_DequeueCount.reset(); + m_EnqueueRace.reset(); + m_DequeueRace.reset(); + m_AdvanceTailError.reset(); + m_BadTail.reset(); + m_EmptyDequeue.reset(); + } + + stat& operator +=(stat const& s) + { + m_EnqueueCount += s.m_EnqueueCount.get(); + m_DequeueCount += s.m_DequeueCount.get(); + m_EnqueueRace += s.m_EnqueueRace.get(); + m_DequeueRace += s.m_DequeueRace.get(); + m_AdvanceTailError += s.m_AdvanceTailError.get(); + m_BadTail += s.m_BadTail.get(); + m_EmptyDequeue += s.m_EmptyDequeue.get(); + + return *this; + }*/ + //@endcond + }; + + /// MSPriorityQueue empty statistics + struct empty_stat { + //@cond + void onEnqueSuccess() const {} + void onDequeSuccess() const {} + + void onQueueCreate() const {} + void onRepeatEnque() const {} + + void onReturnEmpty() const {} + void onCloseQueue() const {} + + void reset() {} + empty_stat& operator +=(empty_stat const&) + { + return *this; + } + //@endcond + }; + + /// MSQueue default traits + struct traits + { + typedef speculative_pairing_queue::base_hook<> hook; + /// Back-off strategy + typedef cds::backoff::empty back_off; + + /// The functor used for dispose removed items. Default is \p opt::v::empty_disposer. This option is used for dequeuing + typedef opt::v::empty_disposer disposer; + + /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter to enable item counting + typedef atomicity::empty_item_counter item_counter; + + /// Internal statistics (by default, disabled) + /** + Possible option value are: \p msqueue::stat, \p msqueue::empty_stat (the default), + user-provided class that supports \p %msqueue::stat interface. + */ + typedef speculative_pairing_queue::empty_stat stat; + + /// C++ memory ordering model + /** + Can be \p opt::v::relaxed_ordering (relaxed memory model, the default) + or \p opt::v::sequential_consistent (sequentially consisnent memory model). + */ + typedef opt::v::sequential_consistent memory_model; + + /// Link checking, see \p cds::opt::link_checker + static constexpr const opt::link_check_type link_checker = opt::debug_check_link; + + /// Padding for internal critical atomic data. Default is \p opt::cache_line_padding + enum { padding = opt::cache_line_padding }; + }; + + /// Metafunction converting option list to traits + /** + \p Options: + - \p opt::buffer - the buffer type for heap array. Possible type are: \p opt::v::initialized_static_buffer, \p opt::v::initialized_dynamic_buffer. + Default is \p %opt::v::initialized_dynamic_buffer. + You may specify any type of value for the buffer since at instantiation time + the \p buffer::rebind member metafunction is called to change the type of values stored in the buffer. + - \p opt::compare - priority compare functor. No default functor is provided. + If the option is not specified, the \p opt::less is used. + - \p opt::less - specifies binary predicate used for priority compare. Default is \p std::less. + - \p opt::lock_type - lock type. Default is \p cds::sync::spin + - \p opt::back_off - back-off strategy. Default is \p cds::backoff::yield + - \p opt::stat - internal statistics. Available types: \p mspriority_queue::stat, \p mspriority_queue::empty_stat (the default, no overhead) + */ + template + struct make_traits { +# ifdef CDS_DOXYGEN_INVOKED + typedef implementation_defined type ; ///< Metafunction result +# else + typedef typename cds::opt::make_options< + typename cds::opt::find_type_traits< traits, Options... >::type + ,Options... + >::type type; +# endif + }; + + } // namespace mspriority_queue + + /// Michael & Scott array-based lock-based concurrent priority queue heap + /** @ingroup cds_intrusive_priority_queue + Source: + - [2013] Henzinger,Payer,Sezgin " + Replacing competition with cooperation to achieve scalable lock-free FIFO queues" + + Template parameters: + - \p T - type to be stored in the queue. The priority is a part of \p T type. + - \p Traits - type traits. See \p speculative_pairing_queue::traits for explanation. + It is possible to declare option-based queue with \p cds::container::speculative_pairing_queue::make_traits + metafunction instead of \p Traits template argument. + */ + template + class SPQueue + { + public: + typedef GC gc ; ///< Garbage collector + typedef T value_type ; ///< Value type stored in the queue + typedef Traits traits ; ///< Traits template parameter + + typedef typename traits::hook hook; + typedef typename hook::node_type node_type; ///< node type + typedef typename get_node_traits< value_type, node_type, hook>::type node_traits; ///< node traits + typedef typename sp_queue::get_link_checker< node_type, traits::link_checker >::type link_checker; ///< link checker + typedef typename traits::back_off back_off; ///< back-off strategy + typedef typename traits::item_counter item_counter; ///< Item counter class + typedef typename traits::stat stat; ///< Internal statistics + typedef typename traits::memory_model memory_model; ///< Memory ordering. See \p cds::opt::memory_model option + typedef typename traits::disposer disposer; ///< disposer used + + /// Rebind template arguments + template + struct rebind { + typedef SPQueue< GC2, T2, Traits2 > other; ///< Rebinding result + }; + + static constexpr const size_t c_nHazardPtrCount = 5; ///< Count of hazard pointer required for the algorithm + protected: + typedef typename node_type::atomic_node_ptr atomic_node_ptr; + static_assert((std::is_same::value),"GC and node_type::gc must be the same"); + + + //@cond + /// Slot type + typedef struct SlotType { + atomic_node_ptr m_pHead; + atomic_node_ptr m_pLast; + atomic_node_ptr m_pRemoved; + + SlotType(){ + m_pHead.store(nullptr, memory_model::memory_order_release); + m_pLast.store(nullptr, memory_model::memory_order_release); + m_pRemoved.store(nullptr, memory_model::memory_order_release); + } + } Slot; + //@endcond + const static size_t C_SIZE = 10; ///< size + int probStale = 0; //< propability of dispose stale nodes + //@cond + /// Queue type + typedef struct QueueType { + typedef typename gc::template atomic_type atomic_int; + typedef typename gc::template atomic_type atomic_bool; + + atomic_bool m_Invalid; + atomic_int m_Cntdeq; + atomic_int m_Tail; + Slot m_pair[10]; + + QueueType(){ + m_Invalid.store(false, memory_model::memory_order_release); + m_Tail.store(0, memory_model::memory_order_release); + m_Cntdeq.store(0, memory_model::memory_order_release); + } + + QueueType(int tail){ + m_Invalid.store(false, memory_model::memory_order_release); + m_Tail.store(tail, memory_model::memory_order_release); + m_Cntdeq.store(0, memory_model::memory_order_release); + } + } Queue; + //@endcond + + typedef typename gc::template atomic_ref atomic_queue_ptr; + + item_counter m_ItemCounter ; ///< Item counter + stat m_Stat ; ///< internal statistics accumulator + atomic_queue_ptr m_Queue ; ///< Global queue + + static node_type* PICKET; + + + + static void clear_links( node_type * pNode ) + { + pNode->m_pNext.store( nullptr, memory_model::memory_order_release ); + pNode->m_nVer.store(0, memory_model::memory_order_release); + pNode->m_removed = false; + } + + struct disposer_node_thunk { + void operator()( value_type * p ) const + { + assert( p != nullptr ); + SPQueue::clear_links( node_traits::to_node_ptr( p )); + disposer()(p); + } + }; + + static void dispose_node( node_type * p ) + { + //retire all except PICKET + if (p != PICKET) + { + gc::template retire( node_traits::to_value_ptr( p )); + } + } + + + static void dispose_queue( Queue* queue) + { + + struct disposer_thunk { + void operator()( Queue* queue ) const + { + assert(queue != nullptr); + + node_type* current_node; + for (int i = 0; i < C_SIZE; i++) + { + current_node = queue->m_pair[i].m_pHead.load(memory_model::memory_order_acquire); + while (current_node != nullptr) + { + node_type* next_node = current_node->m_pNext.load(memory_model::memory_order_acquire); + if (current_node != PICKET) + disposer_node_thunk()(node_traits::to_value_ptr( current_node )); + current_node = next_node; + } + } + //there must be queue disposer, buuuuuut... + delete queue; + } + }; + + gc::template retire(queue); + } + +/* void dispose_stale_nodes( Slot &slot){ + boost::mt19937 gen; + boost::uniform_int<> dist(0,99); + boost::variate_generator > roll(gen, dist); + + int random_int = roll(); + //EXPECT_TRUE(false) << "lol"; + if (random_int < probStale) + { + + typename gc::template Guard node_guard; + typename std::list stale_nodes; + node_type* head = node_guard.protect(slot.m_pHead); + node_type* curr = head; + node_type* last = curr; + //EXPECT_TRUE(false) << "head" << node_traits::to_value_ptr(head->m_pNext)->nVal; + + while (curr != nullptr && curr->m_removed){ + //if (current_node != PICKET) + stale_nodes.push_back(curr); + curr = node_guard.protect(curr->m_pNext); + } + + if (stale_nodes.size() > 0) + { + if (slot.m_pHead.compare_exchange_strong(head, + last, + memory_model::memory_order_relaxed, + memory_model::memory_order_relaxed)){ + stale_nodes.pop_back(); + + for (typename std::list::iterator it = stale_nodes.begin(); it != stale_nodes.end(); it++){ + //EXPECT_TRUE(false) << "Dis stale" << node_traits::to_value_ptr(*it)->nVal; + dispose_node(*it); + } + } + } + + } + } +*/ + + public: + /// Constructs empty speculative pairing queue + /** + */ + void changeProbStale(int prob) + { + probStale = prob; + } + + SPQueue() + { + m_Queue.store(new Queue, memory_model::memory_order_release); + PICKET->m_nVer.store(-1, memory_model::memory_order_release); + } + + /// Clears priority queue and destructs the object + ~SPQueue() + { + clear(); + //delete PICKET; + } + + /// Inserts a item into priority queue + /** + + */ + bool enqueue( value_type& val ) + { + node_type* DUMMY = nullptr; + Queue* pQueue; + typename gc::template Guard queue_guard; + typename gc::template GuardArray<3> guards; + size_t tail; + + while (true){ + tail = 0; + pQueue = queue_guard.protect(m_Queue); + if (pQueue->m_Invalid.load(memory_model::memory_order_acquire)) { + Queue* pNewQueue = createNewQueue(val); + if (m_Queue.compare_exchange_strong(pQueue, pNewQueue, memory_model::memory_order_seq_cst,memory_model::memory_order_seq_cst)) { + dispose_queue(pQueue); + m_Stat.onQueueCreate(); + ++m_ItemCounter; + return true; + } else { + delete pNewQueue; + } + + m_Stat.onRepeatEnque(); + continue; + } + + tail = pQueue->m_Tail.load(memory_model::memory_order_seq_cst); + + size_t idx = tail % C_SIZE; + + guards.protect(0, pQueue->m_pair[idx].m_pLast); + guards.protect(1, pQueue->m_pair[idx].m_pHead); + + node_type* pNode = guards.protect(2, pQueue->m_pair[idx].m_pLast, [](node_type * p) -> value_type * {return node_traits::to_value_ptr(p);}); + + if (tail == idx) { + if (pNode == nullptr) { + + node_type* pNewNode = node_traits::to_node_ptr( val ); + pNewNode->m_nVer.store(tail, memory_model::memory_order_release); + + node_type* DUMMY = nullptr; + if (pQueue->m_pair[idx].m_pHead.compare_exchange_strong(DUMMY, pNewNode, memory_model::memory_order_seq_cst, memory_model::memory_order_seq_cst)) { + pQueue->m_pair[idx].m_pLast.store(pNewNode, memory_model::memory_order_release); + break; + } + else { + if (pQueue->m_pair[idx].m_pHead.load(memory_model::memory_order_acquire) == PICKET) + pQueue->m_Invalid.store(true, memory_model::memory_order_release); + else + pQueue->m_Tail.compare_exchange_weak(tail, + tail + 1, + memory_model::memory_order_seq_cst, + memory_model::memory_order_seq_cst); + m_Stat.onRepeatEnque(); + continue; + } + } + else { + if (pNode == PICKET) + pQueue->m_Invalid.store(true, memory_model::memory_order_release); + else + pQueue->m_Tail.compare_exchange_weak(tail, + tail + 1, + memory_model::memory_order_seq_cst, + memory_model::memory_order_seq_cst); + + m_Stat.onRepeatEnque(); + continue; + } + } + + if (pNode == nullptr) + { + pNode = guards.protect(2, pQueue->m_pair[idx].m_pHead, [](node_type * p) -> value_type * {return node_traits::to_value_ptr(p);}); + } + + if (pNode == PICKET) { + Queue* pNewQueue = createNewQueue(val); + if (m_Queue.compare_exchange_strong(pQueue, pNewQueue,memory_model::memory_order_seq_cst,memory_model::memory_order_acquire)) + { + dispose_queue(pQueue); + m_Stat.onQueueCreate(); + ++m_ItemCounter; + return true; + } else { + delete pNewQueue; + } + + m_Stat.onRepeatEnque(); + continue; + } + + while (pNode->m_pNext.load(memory_model::memory_order_acquire) != nullptr + && pNode->m_nVer.load(memory_model::memory_order_acquire) < tail) + pNode = guards.protect(2, pNode->m_pNext, [](node_type * p) -> value_type * {return node_traits::to_value_ptr(p);}); + + if (pNode->m_nVer.load(memory_model::memory_order_acquire) >= tail) { + pQueue->m_Tail.compare_exchange_strong(tail, tail + 1,memory_model::memory_order_seq_cst,memory_model::memory_order_seq_cst); + m_Stat.onRepeatEnque(); + continue; + } + + if (pNode != PICKET) { + node_type* pNewNode = node_traits::to_node_ptr(val); + pNewNode->m_nVer.store(tail, memory_model::memory_order_release); + node_type* DUMMY = nullptr; + if (pNode->m_pNext.compare_exchange_strong(DUMMY, pNewNode,memory_model::memory_order_seq_cst,memory_model::memory_order_seq_cst)) { + pQueue->m_pair[idx].m_pLast.store(pNewNode, memory_model::memory_order_release); + break; + } + } + else { + pQueue->m_Invalid.store(true, memory_model::memory_order_release); + } + } + pQueue->m_Tail.compare_exchange_weak(tail, tail + 1,memory_model::memory_order_seq_cst,memory_model::memory_order_seq_cst); + ++m_ItemCounter; + m_Stat.onEnqueSuccess(); + return true; + } + + /// Extracts item with high priority + /** + + */ + value_type* dequeue() + { + node_type* DUMMY = nullptr; + typename gc::template Guard queue_guard; + typename gc::template GuardArray<3> guards; + + Queue* pQueue = queue_guard.protect(m_Queue); + if (pQueue->m_Invalid.load(memory_model::memory_order_acquire)) { + m_Stat.onReturnEmpty(); + return nullptr; + } + + + size_t ticket = pQueue->m_Cntdeq++;//.fetch_add(1, memory_model::memory_order_seq_cst); + /*====== ТОТ САМЫЙ ВЫВОД TICKET =====*/ + //std::string s = std::to_string(ticket) + "\n"; + //std::cerr << s; + + size_t idx = ticket % C_SIZE; + guards.protect(0, pQueue->m_pair[idx].m_pRemoved); + guards.protect(1, pQueue->m_pair[idx].m_pHead); + + //dispose_stale_nodes(pQueue->m_pair[idx]); + + //guards.protect(1, pQueue->m_pair[idx].m_pHead); + + if (ticket >= pQueue->m_Tail.load(memory_model::memory_order_acquire) && ticket == idx) {//Error in article. may be must be >= + node_type* DUMMY = nullptr; + if (pQueue->m_pair[idx].m_pHead.compare_exchange_strong(DUMMY, PICKET, memory_model::memory_order_seq_cst,memory_model::memory_order_acquire)) { + CloseQueue(pQueue, idx); + m_Stat.onCloseQueue(); + return nullptr; + } + } + + node_type* pNode = guards.protect(2, pQueue->m_pair[idx].m_pRemoved, [](node_type * p) -> value_type * {return node_traits::to_value_ptr(p);}); + if (pNode == nullptr || pNode == PICKET) + pNode = guards.protect(2, pQueue->m_pair[idx].m_pHead, [](node_type * p) -> value_type * {return node_traits::to_value_ptr(p);}); + + if (pNode == PICKET) { + CloseQueue(pQueue, idx); + m_Stat.onCloseQueue(); + return nullptr; + } + + if (pNode->m_nVer.load(memory_model::memory_order_acquire) > ticket) + pNode = guards.protect(2, pQueue->m_pair[idx].m_pHead, [](node_type * p) -> value_type * {return node_traits::to_value_ptr(p);}); + + while (pNode->m_nVer.load(memory_model::memory_order_acquire) < ticket) { + if (pNode->m_pNext.load(memory_model::memory_order_acquire) == nullptr) { + node_type* DUMMY = nullptr; + if (pNode->m_pNext.compare_exchange_strong(DUMMY, PICKET, memory_model::memory_order_seq_cst, memory_model::memory_order_acquire)) { + CloseQueue(pQueue, idx); + m_Stat.onCloseQueue(); + return nullptr; + } + } + pNode = guards.protect(2, pNode->m_pNext, [](node_type * p) -> value_type * {return node_traits::to_value_ptr(p);}); + if (pNode == PICKET) { + CloseQueue(pQueue, idx); + m_Stat.onCloseQueue(); + return nullptr; + } + } + + value_type* x = node_traits::to_value_ptr(pNode); + pQueue->m_pair[idx].m_pRemoved.store(pNode, memory_model::memory_order_release); + //pNode->m_removed = true; + --m_ItemCounter; + m_Stat.onDequeSuccess(); + return x; + } + + bool push(value_type& val){ + return enqueue(val); + } + + value_type* pop(){ + return dequeue(); + } + /// Clears the queue (not atomic) + /** + + */ + void clear() + { + while ( dequeue() != nullptr); + dispose_queue(m_Queue.load(memory_model::memory_order_acquire)); + m_Queue.store(new Queue(), memory_model::memory_order_release); + } + + /// Checks is the priority queue is empty + bool empty() const + { + Queue* pQueue = m_Queue.load(memory_model::memory_order_acquire); + return pQueue->m_Tail.load(memory_model::memory_order_acquire) <= + pQueue->m_Cntdeq.load(memory_model::memory_order_acquire); + } + + /// Returns current size of priority queue + size_t size() const + { + return m_ItemCounter.value(); + } + + /// Returns const reference to internal statistics + stat const& statistics() const + { + return m_Stat; + } + + protected: + Queue* createNewQueue(value_type& x) { + Queue* queue = new Queue(1); + + node_type* pNewNode = node_traits::to_node_ptr(x); + pNewNode->m_nVer.store(0, memory_model::memory_order_release); + queue->m_pair[0].m_pHead.store(pNewNode, memory_model::memory_order_release); + queue->m_pair[0].m_pLast.store(pNewNode, memory_model::memory_order_release); + + return queue; + } + + void CloseQueue(Queue* q, int idx) { + q->m_Invalid.store(true, memory_model::memory_order_release); + q->m_pair[idx].m_pRemoved.store(PICKET, memory_model::memory_order_release); + } + }; + + template + typename SPQueue::node_type* SPQueue::PICKET = new SPQueue::node_type(); + }} // namespace cds::intrusive + +#endif // #ifndef CDSLIB_INTRUSIVE_MSPRIORITY_QUEUE_H diff --git a/test/stress/queue/CMakeLists.txt b/test/stress/queue/CMakeLists.txt index a074aceed..35bcc1325 100644 --- a/test/stress/queue/CMakeLists.txt +++ b/test/stress/queue/CMakeLists.txt @@ -10,7 +10,7 @@ set(CDSSTRESS_QUEUE_POP_SOURCES ) add_executable(${CDSSTRESS_QUEUE_POP} ${CDSSTRESS_QUEUE_POP_SOURCES}) target_link_libraries(${CDSSTRESS_QUEUE_POP} ${CDS_TEST_LIBRARIES} ${CDSSTRESS_FRAMEWORK_LIBRARY}) -add_test(NAME ${CDSSTRESS_QUEUE_POP} COMMAND ${CDSSTRESS_QUEUE_POP} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) +add_test(NAME ${CDSSTRESS_QUEUE_POP} COMMAND ${CDSSTRESS_QUEUE_POP} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) # stress-queue-push set(CDSSTRESS_QUEUE_PUSH stress-queue-push) @@ -20,18 +20,18 @@ set(CDSSTRESS_QUEUE_PUSH_SOURCES ) add_executable(${CDSSTRESS_QUEUE_PUSH} ${CDSSTRESS_QUEUE_PUSH_SOURCES}) target_link_libraries(${CDSSTRESS_QUEUE_PUSH} ${CDS_TEST_LIBRARIES} ${CDSSTRESS_FRAMEWORK_LIBRARY}) -add_test(NAME ${CDSSTRESS_QUEUE_PUSH} COMMAND ${CDSSTRESS_QUEUE_PUSH} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) +add_test(NAME ${CDSSTRESS_QUEUE_PUSH} COMMAND ${CDSSTRESS_QUEUE_PUSH} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) # stress-queue-push-pop set(CDSSTRESS_QUEUE_PUSHPOP stress-queue-push-pop) set(CDSSTRESS_QUEUE_PUSHPOP_SOURCES ../main.cpp push_pop.cpp - intrusive_push_pop.cpp + intrusive_push_pop.cpp ) add_executable(${CDSSTRESS_QUEUE_PUSHPOP} ${CDSSTRESS_QUEUE_PUSHPOP_SOURCES}) target_link_libraries(${CDSSTRESS_QUEUE_PUSHPOP} ${CDS_TEST_LIBRARIES} ${CDSSTRESS_FRAMEWORK_LIBRARY}) -add_test(NAME ${CDSSTRESS_QUEUE_PUSHPOP} COMMAND ${CDSSTRESS_QUEUE_PUSHPOP} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) +add_test(NAME ${CDSSTRESS_QUEUE_PUSHPOP} COMMAND ${CDSSTRESS_QUEUE_PUSHPOP} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) # stress-queue-random set(CDSSTRESS_QUEUE_RANDOM stress-queue-random) @@ -41,7 +41,7 @@ set(CDSSTRESS_QUEUE_RANDOM_SOURCES ) add_executable(${CDSSTRESS_QUEUE_RANDOM} ${CDSSTRESS_QUEUE_RANDOM_SOURCES}) target_link_libraries(${CDSSTRESS_QUEUE_RANDOM} ${CDS_TEST_LIBRARIES} ${CDSSTRESS_FRAMEWORK_LIBRARY}) -add_test(NAME ${CDSSTRESS_QUEUE_RANDOM} COMMAND ${CDSSTRESS_QUEUE_RANDOM} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) +add_test(NAME ${CDSSTRESS_QUEUE_RANDOM} COMMAND ${CDSSTRESS_QUEUE_RANDOM} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) # stress-queue-bounded set(CDSSTRESS_QUEUE_BOUNDED stress-queue-bounded) @@ -51,7 +51,7 @@ set(CDSSTRESS_QUEUE_BOUNDED_SOURCES ) add_executable(${CDSSTRESS_QUEUE_BOUNDED} ${CDSSTRESS_QUEUE_BOUNDED_SOURCES}) target_link_libraries(${CDSSTRESS_QUEUE_BOUNDED} ${CDS_TEST_LIBRARIES} ${CDSSTRESS_FRAMEWORK_LIBRARY}) -add_test(NAME ${CDSSTRESS_QUEUE_BOUNDED} COMMAND ${CDSSTRESS_QUEUE_BOUNDED} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) +add_test(NAME ${CDSSTRESS_QUEUE_BOUNDED} COMMAND ${CDSSTRESS_QUEUE_BOUNDED} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) # stress-spsc-queue set(CDSSTRESS_SPSC_QUEUE stress-spsc-queue) @@ -64,7 +64,6 @@ add_executable(${CDSSTRESS_SPSC_QUEUE} ${CDSSTRESS_SPSC_QUEUE_SOURCES}) target_link_libraries(${CDSSTRESS_SPSC_QUEUE} ${CDS_TEST_LIBRARIES} ${CDSSTRESS_FRAMEWORK_LIBRARY}) add_test(NAME ${CDSSTRESS_SPSC_QUEUE} COMMAND ${CDSSTRESS_SPSC_QUEUE} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) - # stress-queue add_custom_target( stress-queue DEPENDS diff --git a/test/stress/queue/intrusive_push_pop.cpp b/test/stress/queue/intrusive_push_pop.cpp index a6af373b2..9115bd22d 100644 --- a/test/stress/queue/intrusive_push_pop.cpp +++ b/test/stress/queue/intrusive_push_pop.cpp @@ -1,7 +1,32 @@ -// Copyright (c) 2006-2018 Maxim Khizhinsky -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #include "intrusive_queue_type.h" #include @@ -314,7 +339,6 @@ namespace { } } pool.add( new Consumer( pool, q ), s_nReaderThreadCount ); - std::chrono::milliseconds duration = pool.run(); propout() << std::make_pair( "duration", duration ); @@ -331,6 +355,7 @@ namespace { analyze( q, nLeftOffset, nRightOffset ); + propout() << q.statistics(); } }; @@ -348,6 +373,16 @@ namespace { queue_type::gc::force_dispose(); \ } + + CDSSTRESS_QUEUE_F( SPQueue_HP, cds::intrusive::speculative_pairing_queue::node ) + CDSSTRESS_QUEUE_F( SPQueue_HP_ic, cds::intrusive::speculative_pairing_queue::node ) + CDSSTRESS_QUEUE_F( SPQueue_HP_stat, cds::intrusive::speculative_pairing_queue::node ) + CDSSTRESS_QUEUE_F( SPQueue_DHP, cds::intrusive::speculative_pairing_queue::node ) + CDSSTRESS_QUEUE_F( SPQueue_DHP_ic, cds::intrusive::speculative_pairing_queue::node ) + CDSSTRESS_QUEUE_F( SPQueue_DHP_stat, cds::intrusive::speculative_pairing_queue::node ) + + + CDSSTRESS_QUEUE_F( MSQueue_HP, cds::intrusive::msqueue::node ) CDSSTRESS_QUEUE_F( MSQueue_HP_ic, cds::intrusive::msqueue::node ) CDSSTRESS_QUEUE_F( MSQueue_HP_stat, cds::intrusive::msqueue::node ) @@ -375,6 +410,7 @@ namespace { CDSSTRESS_QUEUE_F( BasketQueue_DHP, cds::intrusive::basket_queue::node ) CDSSTRESS_QUEUE_F( BasketQueue_DHP_ic, cds::intrusive::basket_queue::node ) CDSSTRESS_QUEUE_F( BasketQueue_DHP_stat, cds::intrusive::basket_queue::node ) + #undef CDSSTRESS_QUEUE_F @@ -399,6 +435,7 @@ namespace { CDSSTRESS_QUEUE_F(FCQueue_list_wait_sm_stat, boost::intrusive::list_base_hook<> ) CDSSTRESS_QUEUE_F(FCQueue_list_wait_mm, boost::intrusive::list_base_hook<> ) CDSSTRESS_QUEUE_F(FCQueue_list_wait_mm_stat, boost::intrusive::list_base_hook<> ) + #undef CDSSTRESS_QUEUE_F @@ -413,6 +450,7 @@ namespace { CDSSTRESS_QUEUE_F( VyukovMPMCCycleQueue_dyn ) CDSSTRESS_QUEUE_F( VyukovMPMCCycleQueue_dyn_ic ) + #undef CDSSTRESS_QUEUE_F diff --git a/test/stress/queue/intrusive_queue_type.h b/test/stress/queue/intrusive_queue_type.h index f6ef2e64c..5142add72 100644 --- a/test/stress/queue/intrusive_queue_type.h +++ b/test/stress/queue/intrusive_queue_type.h @@ -1,7 +1,32 @@ -// Copyright (c) 2006-2018 Maxim Khizhinsky -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef CDSSTRESS_INTRUSIVE_QUEUE_TYPES_H #define CDSSTRESS_INTRUSIVE_QUEUE_TYPES_H @@ -13,6 +38,7 @@ #include #include #include +#include #include #include @@ -136,7 +162,7 @@ namespace queue { }; typedef cds::intrusive::MSQueue< cds::gc::DHP, T, traits_MSQueue_DHP_ic > MSQueue_DHP_ic; typedef cds::intrusive::MoirQueue< cds::gc::DHP, T, traits_MSQueue_DHP_ic > MoirQueue_DHP_ic; - + // MSQueue + stat struct traits_MSQueue_HP_stat : public cds::intrusive::msqueue::traits { @@ -155,6 +181,62 @@ namespace queue { typedef cds::intrusive::MoirQueue< cds::gc::DHP, T, traits_MSQueue_DHP_stat > MoirQueue_DHP_stat; + struct traits_SPQueue_HP : public cds::intrusive::speculative_pairing_queue::traits + { + typedef cds::intrusive::sp_queue::base_hook< cds::opt::gc< cds::gc::HP > > hook; + }; + typedef cds::intrusive::SPQueue< cds::gc::HP, T, traits_SPQueue_HP > SPQueue_HP; + + struct traits_SPQueue_HP_seqcst : public cds::intrusive::speculative_pairing_queue::traits + { + typedef cds::intrusive::sp_queue::base_hook< cds::opt::gc< cds::gc::HP > > hook; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef cds::intrusive::SPQueue< cds::gc::HP, T, traits_SPQueue_HP_seqcst > SPQueue_HP_seqcst; + + struct traits_SPQueue_DHP : public cds::intrusive::speculative_pairing_queue::traits + { + typedef cds::intrusive::sp_queue::base_hook< cds::opt::gc< cds::gc::DHP > > hook; + }; + typedef cds::intrusive::SPQueue< cds::gc::DHP, T, traits_SPQueue_DHP > SPQueue_DHP; + + struct traits_SPQueue_DHP_seqcst : public cds::intrusive::speculative_pairing_queue::traits + { + typedef cds::intrusive::sp_queue::base_hook< cds::opt::gc< cds::gc::DHP > > hook; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef cds::intrusive::SPQueue< cds::gc::DHP, T, traits_SPQueue_DHP_seqcst > SPQueue_DHP_seqcst; + + // SPQueue + item counter + struct traits_SPQueue_HP_ic : public cds::intrusive::speculative_pairing_queue::traits + { + typedef cds::intrusive::sp_queue::base_hook< cds::opt::gc< cds::gc::HP > > hook; + typedef cds::atomicity::item_counter item_counter; + }; + typedef cds::intrusive::SPQueue< cds::gc::HP, T, traits_SPQueue_HP_ic > SPQueue_HP_ic; + + struct traits_SPQueue_DHP_ic : public cds::intrusive::speculative_pairing_queue::traits + { + typedef cds::intrusive::sp_queue::base_hook< cds::opt::gc< cds::gc::DHP > > hook; + typedef cds::atomicity::item_counter item_counter; + }; + typedef cds::intrusive::SPQueue< cds::gc::DHP, T, traits_SPQueue_DHP_ic > SPQueue_DHP_ic; + + // SPQueue + stat + struct traits_SPQueue_HP_stat : public cds::intrusive::speculative_pairing_queue::traits + { + typedef cds::intrusive::sp_queue::base_hook< cds::opt::gc< cds::gc::HP > > hook; + typedef cds::intrusive::speculative_pairing_queue::stat<> stat; + }; + typedef cds::intrusive::SPQueue< cds::gc::HP, T, traits_SPQueue_HP_stat > SPQueue_HP_stat; + + struct traits_SPQueue_DHP_stat : public cds::intrusive::speculative_pairing_queue::traits + { + typedef cds::intrusive::sp_queue::base_hook< cds::opt::gc< cds::gc::DHP > > hook; + typedef cds::intrusive::speculative_pairing_queue::stat<> stat; + }; + typedef cds::intrusive::SPQueue< cds::gc::DHP, T, traits_SPQueue_DHP_stat > SPQueue_DHP_stat; + // OptimisticQueue struct traits_OptimisticQueue_HP : public cds::intrusive::optimistic_queue::traits { diff --git a/test/stress/queue/pop.cpp b/test/stress/queue/pop.cpp index 5dbb72cd5..379449ebd 100644 --- a/test/stress/queue/pop.cpp +++ b/test/stress/queue/pop.cpp @@ -1,7 +1,32 @@ -// Copyright (c) 2006-2018 Maxim Khizhinsky -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #include "queue_type.h" @@ -125,8 +150,11 @@ namespace { pool.add( new Consumer( pool, q ), s_nThreadCount ); - for ( size_t i = 0; i < s_nQueueSize; ++i ) + for ( size_t i = 0; i < s_nQueueSize; ++i ) { q.push( i ); + } + + propout() << std::make_pair( "thread_count", s_nThreadCount ) << std::make_pair( "push_count", s_nQueueSize ); @@ -141,7 +169,9 @@ namespace { } }; + CDSSTRESS_MSQueue( queue_pop ) + CDSSTRESS_SPQueue( queue_pop ) CDSSTRESS_MoirQueue( queue_pop ) CDSSTRESS_BasketQueue( queue_pop ) CDSSTRESS_OptimsticQueue( queue_pop ) @@ -159,8 +189,10 @@ namespace { test( queue ); \ } + CDSSTRESS_VyukovQueue( queue_pop ) + #undef CDSSTRESS_Queue_F @@ -216,6 +248,7 @@ namespace { CDSSTRESS_SegmentedQueue( segmented_queue_pop ) + #ifdef CDSTEST_GTEST_INSTANTIATE_TEST_CASE_P_HAS_4TH_ARG static std::string get_test_parameter_name( testing::TestParamInfo const& p ) { diff --git a/test/stress/queue/print_stat.h b/test/stress/queue/print_stat.h index 960abdac5..d64aa810d 100644 --- a/test/stress/queue/print_stat.h +++ b/test/stress/queue/print_stat.h @@ -1,7 +1,32 @@ -// Copyright (c) 2006-2018 Maxim Khizhinsky -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef CDSSTRESS_QUEUE_PRINT_STAT_H #define CDSSTRESS_QUEUE_PRINT_STAT_H @@ -51,6 +76,23 @@ namespace cds_test { return o; } + template + static inline property_stream& operator <<( property_stream& o, cds::intrusive::speculative_pairing_queue::stat const& s ) + { + return o + << CDSSTRESS_STAT_OUT( s, m_nEnqueCount ) + << CDSSTRESS_STAT_OUT( s, m_nQueueCreatingCount ) + << CDSSTRESS_STAT_OUT( s, m_nRepeatEnqueCount ) + << CDSSTRESS_STAT_OUT( s, m_nDequeCount ) + << CDSSTRESS_STAT_OUT( s, m_nReturnEmptyInvalid ) + << CDSSTRESS_STAT_OUT( s, m_nClosingQueue ); + } + + static inline property_stream& operator <<( property_stream& o, cds::intrusive::speculative_pairing_queue::empty_stat const& ) + { + return o; + } + template static inline property_stream& operator <<( property_stream& o, cds::intrusive::optimistic_queue::stat const& s ) { diff --git a/test/stress/queue/push.cpp b/test/stress/queue/push.cpp index c2e80bba2..1f1304cc8 100644 --- a/test/stress/queue/push.cpp +++ b/test/stress/queue/push.cpp @@ -1,7 +1,32 @@ -// Copyright (c) 2006-2018 Maxim Khizhinsky -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #include "queue_type.h" @@ -57,8 +82,10 @@ namespace { virtual void test() { for ( size_t nItem = m_nStartItem; nItem < m_nEndItem; ++nItem ) { - if ( !m_Queue.push( nItem )) + if ( !m_Queue.push( nItem )) { ++m_nPushError; + } + //EXPECT_TRUE(false) << "nItem = " << nItem; } } @@ -89,6 +116,7 @@ namespace { template void test( Queue& q ) { + try { cds_test::thread_pool& pool = get_pool(); pool.add( new Producer( pool, q ), s_nThreadCount ); @@ -113,6 +141,11 @@ namespace { analyze( q ); propout() << q.statistics(); + } + catch (std::exception& e) + { + EXPECT_TRUE(false) << "Exception catched : " << e.what(); + } } template @@ -132,6 +165,7 @@ namespace { size_t nPopped = 0; value_type val; + while ( q.pop( val )) { nPopped++; ++arr[ val.nNo ]; @@ -144,7 +178,9 @@ namespace { } }; + CDSSTRESS_MSQueue( queue_push ) + CDSSTRESS_SPQueue( queue_push ) CDSSTRESS_MoirQueue( queue_push ) CDSSTRESS_BasketQueue( queue_push ) CDSSTRESS_OptimsticQueue( queue_push ) @@ -153,6 +189,7 @@ namespace { CDSSTRESS_RWQueue( queue_push ) CDSSTRESS_StdQueue( queue_push ) + #undef CDSSTRESS_Queue_F #define CDSSTRESS_Queue_F( test_fixture, type_name ) \ TEST_F( test_fixture, type_name ) \ diff --git a/test/stress/queue/push_pop.cpp b/test/stress/queue/push_pop.cpp index 4803f5238..280d35c40 100644 --- a/test/stress/queue/push_pop.cpp +++ b/test/stress/queue/push_pop.cpp @@ -1,7 +1,32 @@ -// Copyright (c) 2006-2018 Maxim Khizhinsky -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #include "queue_type.h" @@ -321,6 +346,7 @@ namespace { using simple_queue_push_pop = queue_push_pop<>; CDSSTRESS_MSQueue( simple_queue_push_pop ) + CDSSTRESS_SPQueue( simple_queue_push_pop ) CDSSTRESS_MoirQueue( simple_queue_push_pop ) CDSSTRESS_BasketQueue( simple_queue_push_pop ) CDSSTRESS_OptimsticQueue( simple_queue_push_pop ) @@ -398,6 +424,7 @@ namespace { CDSSTRESS_SegmentedQueue( segmented_queue_push_pop ) + #ifdef CDSTEST_GTEST_INSTANTIATE_TEST_CASE_P_HAS_4TH_ARG static std::string get_test_parameter_name( testing::TestParamInfo const& p ) { diff --git a/test/stress/queue/queue_type.h b/test/stress/queue/queue_type.h index 4dd0f454b..c452cac71 100644 --- a/test/stress/queue/queue_type.h +++ b/test/stress/queue/queue_type.h @@ -1,7 +1,32 @@ -// Copyright (c) 2006-2018 Maxim Khizhinsky -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef CDSSTRESS_QUEUE_TYPES_H #define CDSSTRESS_QUEUE_TYPES_H @@ -16,6 +41,7 @@ #include #include #include +#include #include #include @@ -195,6 +221,35 @@ namespace fc_details{ typedef cds::container::MoirQueue< cds::gc::HP, Value, traits_MSQueue_stat > MoirQueue_HP_stat; typedef cds::container::MoirQueue< cds::gc::DHP, Value, traits_MSQueue_stat > MoirQueue_DHP_stat; + // SPQueue + typedef cds::container::SPQueue SPQueue_HP; + typedef cds::container::SPQueue SPQueue_DHP; + + struct traits_SPQueue_seqcst : public + cds::container::speculative_pairing_queue::make_traits < + cds::opt::memory_model < cds::opt::v::sequential_consistent > + > ::type + {}; + typedef cds::container::SPQueue< cds::gc::HP, Value, traits_SPQueue_seqcst > SPQueue_HP_seqcst; + typedef cds::container::SPQueue< cds::gc::DHP, Value, traits_SPQueue_seqcst > SPQueue_DHP_seqcst; + + // SPQueue + item counter + struct traits_SPQueue_ic : public + cds::container::speculative_pairing_queue::make_traits < + cds::opt::item_counter < cds::atomicity::item_counter > + >::type + {}; + typedef cds::container::SPQueue< cds::gc::HP, Value, traits_SPQueue_ic > SPQueue_HP_ic; + typedef cds::container::SPQueue< cds::gc::DHP, Value, traits_SPQueue_ic > SPQueue_DHP_ic; + + // SPQueue + stat + struct traits_SPQueue_stat: public + cds::container::speculative_pairing_queue::make_traits < + cds::opt::stat< cds::container::speculative_pairing_queue::stat<> > + >::type + {}; + typedef cds::container::SPQueue< cds::gc::HP, Value, traits_SPQueue_stat > SPQueue_HP_stat; + typedef cds::container::SPQueue< cds::gc::DHP, Value, traits_SPQueue_stat > SPQueue_DHP_stat; // OptimisticQueue typedef cds::container::OptimisticQueue< cds::gc::HP, Value > OptimisticQueue_HP; @@ -753,6 +808,7 @@ namespace cds_test { #else # define CDSSTRESS_MSQueue_1( test_fixture ) +# define CDSSTRESS_SPQueue_1( test_fixture ) # define CDSSTRESS_MoirQueue_1( test_fixture ) # define CDSSTRESS_OptimsticQueue_1( test_fixture ) # define CDSSTRESS_BasketQueue_1( test_fixture ) @@ -771,6 +827,13 @@ namespace cds_test { CDSSTRESS_Queue_F( test_fixture, MSQueue_DHP_stat ) \ CDSSTRESS_MSQueue_1( test_fixture ) +#define CDSSTRESS_SPQueue( test_fixture ) \ + CDSSTRESS_Queue_F( test_fixture, SPQueue_HP ) \ + CDSSTRESS_Queue_F( test_fixture, SPQueue_HP_stat ) \ + CDSSTRESS_Queue_F( test_fixture, SPQueue_DHP ) \ + CDSSTRESS_Queue_F( test_fixture, SPQueue_DHP_stat ) \ + CDSSTRESS_SPQueue_1( test_fixture ) + #define CDSSTRESS_MoirQueue( test_fixture ) \ CDSSTRESS_Queue_F( test_fixture, MoirQueue_HP ) \ CDSSTRESS_Queue_F( test_fixture, MoirQueue_HP_stat ) \ diff --git a/test/stress/queue/random.cpp b/test/stress/queue/random.cpp index 357737d9e..27e767d9f 100644 --- a/test/stress/queue/random.cpp +++ b/test/stress/queue/random.cpp @@ -1,7 +1,32 @@ -// Copyright (c) 2006-2018 Maxim Khizhinsky -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #include "queue_type.h" @@ -209,6 +234,7 @@ namespace { }; CDSSTRESS_MSQueue( queue_random ) + CDSSTRESS_SPQueue( queue_random ) CDSSTRESS_MoirQueue( queue_random ) CDSSTRESS_BasketQueue( queue_random ) CDSSTRESS_OptimsticQueue( queue_random ) diff --git a/test/stress/queue/spsc_buffer.cpp b/test/stress/queue/spsc_buffer.cpp index c707ad2c0..37402543c 100644 --- a/test/stress/queue/spsc_buffer.cpp +++ b/test/stress/queue/spsc_buffer.cpp @@ -1,7 +1,32 @@ -// Copyright (c) 2006-2018 Maxim Khizhinsky -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #include "queue_type.h" @@ -46,9 +71,9 @@ namespace { void operator()() { std::random_device rd; - std::mt19937 gen( rd()); + std::mt19937 gen( rd() ); std::uniform_int_distribution dis( 0, 64 * 1024* 1024 ); - quad_sum += std::sqrt( static_cast( dis(gen))); + quad_sum += std::sqrt( static_cast( dis(gen) )); } double result() diff --git a/test/unit/queue/CMakeLists.txt b/test/unit/queue/CMakeLists.txt index aea3e81f4..d144682fd 100644 --- a/test/unit/queue/CMakeLists.txt +++ b/test/unit/queue/CMakeLists.txt @@ -28,6 +28,10 @@ set(CDSGTEST_QUEUE_SOURCES intrusive_segmented_queue_hp.cpp intrusive_segmented_queue_dhp.cpp intrusive_vyukov_queue.cpp + intrusive_speculative_pairing_queue_hp.cpp + intrusive_speculative_pairing_queue_dhp.cpp + speculative_pairing_queue_hp.cpp + speculative_pairing_queue_dhp.cpp ) include_directories( @@ -37,4 +41,4 @@ include_directories( add_executable(${PACKAGE_NAME} ${CDSGTEST_QUEUE_SOURCES}) target_link_libraries(${PACKAGE_NAME} ${CDS_TEST_LIBRARIES}) -add_test(NAME ${PACKAGE_NAME} COMMAND ${PACKAGE_NAME} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) \ No newline at end of file +add_test(NAME ${PACKAGE_NAME} COMMAND ${PACKAGE_NAME} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) diff --git a/test/unit/queue/intrusive_speculative_pairing_queue_dhp.cpp b/test/unit/queue/intrusive_speculative_pairing_queue_dhp.cpp new file mode 100644 index 000000000..6a70fcec4 --- /dev/null +++ b/test/unit/queue/intrusive_speculative_pairing_queue_dhp.cpp @@ -0,0 +1,179 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "test_intrusive_speculative_pairing_queue.h" + +#include +#include +#include + +namespace { + namespace ci = cds::intrusive; + typedef cds::gc::DHP gc_type; + + + class IntrusiveSPQueue_DHP : public cds_test::intrusive_speculative_pairing_queue + { + typedef cds_test::intrusive_speculative_pairing_queue base_class; + + protected: + typedef typename base_class::base_hook_item< ci::speculative_pairing_queue::node> base_item_type; + typedef typename base_class::member_hook_item< ci::speculative_pairing_queue::node> member_item_type; + + void SetUp() + { + typedef ci::SPQueue< gc_type, base_item_type, + typename ci::speculative_pairing_queue::make_traits< + ci::opt::hook< ci::speculative_pairing_queue::base_hook< ci::opt::gc>> + >::type + > queue_type; + + cds::gc::dhp::smr::construct( queue_type::c_nHazardPtrCount ); + cds::threading::Manager::attachThread(); + } + + void TearDown() + { + cds::threading::Manager::detachThread(); + cds::gc::dhp::smr::destruct(); + } + + template + void check_array( V& arr ) + { + for ( size_t i = 0; i < arr.size(); ++i ) { + ASSERT_EQ( arr[i].nDisposeCount, 3 ); + } + } + }; + + TEST_F( IntrusiveSPQueue_DHP, base_hook ) + { + typedef cds::intrusive::SPQueue< gc_type, base_item_type, + typename ci::speculative_pairing_queue::make_traits< + ci::opt::disposer< mock_disposer > + ,ci::opt::hook< ci::speculative_pairing_queue::base_hook< ci::opt::gc>> + >::type + > test_queue; + + std::vector arr; + arr.resize(100); + { + test_queue q; + test(q, arr); + } + gc_type::scan(); + check_array( arr ); + } + + TEST_F( IntrusiveSPQueue_DHP, base_item_counting ) + { + typedef cds::intrusive::SPQueue< gc_type, base_item_type, + typename ci::speculative_pairing_queue::make_traits< + ci::opt::disposer< mock_disposer > + , cds::opt::item_counter< cds::atomicity::item_counter > + , ci::opt::hook< ci::speculative_pairing_queue::base_hook< ci::opt::gc>> + >::type + > test_queue; + + std::vector arr; + arr.resize(100); + { + test_queue q; + test(q, arr); + } + gc_type::scan(); + check_array( arr ); + } + + TEST_F( IntrusiveSPQueue_DHP, base_stat ) + { + struct traits : public ci::speculative_pairing_queue::traits + { + typedef ci::speculative_pairing_queue::base_hook< ci::opt::gc> hook; + typedef mock_disposer disposer; + typedef cds::atomicity::item_counter item_counter; + typedef ci::speculative_pairing_queue::stat<> stat; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef cds::intrusive::SPQueue< gc_type, base_item_type, traits > test_queue; + + std::vector arr; + arr.resize(100); + { + test_queue q; + test(q, arr); + } + gc_type::scan(); + check_array( arr ); + } + + TEST_F( IntrusiveSPQueue_DHP, member_hook ) + { + typedef cds::intrusive::SPQueue< gc_type, member_item_type, + typename ci::speculative_pairing_queue::make_traits< + ci::opt::disposer< mock_disposer > + ,ci::opt::hook< ci::speculative_pairing_queue::member_hook< + offsetof( member_item_type, hMember ), + ci::opt::gc + >> + >::type + > test_queue; + + std::vector arr; + arr.resize( 100 ); + { + test_queue q; + test( q, arr ); + } + gc_type::scan(); + check_array( arr ); + } + + TEST_F( IntrusiveSPQueue_DHP, member_hook_stat ) + { + struct traits : public ci::speculative_pairing_queue::traits + { + typedef ci::speculative_pairing_queue::member_hook< + offsetof( member_item_type, hMember ), + ci::opt::gc + > hook; + typedef mock_disposer disposer; + typedef cds::atomicity::item_counter item_counter; + typedef ci::speculative_pairing_queue::stat<> stat; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef cds::intrusive::SPQueue< gc_type, member_item_type, traits > test_queue; + + std::vector arr; + arr.resize( 100 ); + { + test_queue q; + test( q, arr ); + } + gc_type::scan(); + check_array( arr ); + } + +} // namespace diff --git a/test/unit/queue/intrusive_speculative_pairing_queue_hp.cpp b/test/unit/queue/intrusive_speculative_pairing_queue_hp.cpp new file mode 100644 index 000000000..b2f52dfc3 --- /dev/null +++ b/test/unit/queue/intrusive_speculative_pairing_queue_hp.cpp @@ -0,0 +1,200 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "test_intrusive_speculative_pairing_queue.h" + +#include +#include +#include + +namespace { + namespace ci = cds::intrusive; + typedef cds::gc::HP gc_type; + + + class IntrusiveSPQueue_HP : public cds_test::intrusive_speculative_pairing_queue + { + typedef cds_test::intrusive_speculative_pairing_queue base_class; + + protected: + typedef typename base_class::base_hook_item< ci::speculative_pairing_queue::node> base_item_type; + typedef typename base_class::member_hook_item< ci::speculative_pairing_queue::node> member_item_type; + + void SetUp() + { + typedef ci::SPQueue< gc_type, base_item_type > queue_type; + + cds::gc::hp::GarbageCollector::Construct( queue_type::c_nHazardPtrCount, 1, 16 ); + cds::threading::Manager::attachThread(); + } + + void TearDown() + { + cds::threading::Manager::detachThread(); + cds::gc::hp::GarbageCollector::Destruct( true ); + } + + template + void check_array( V& arr ) + { + for ( size_t i = 0; i < arr.size(); ++i ) { + ASSERT_EQ( arr[i].nDisposeCount, 3 ) << "i=" << i; + } + } + }; + + TEST_F( IntrusiveSPQueue_HP, defaulted ) + { + typedef cds::intrusive::SPQueue< gc_type, base_item_type, + typename ci::speculative_pairing_queue::make_traits< + ci::opt::disposer< mock_disposer > + >::type + > test_queue; + + + std::vector arr; + arr.resize(100); + { + test_queue q; + test(q, arr); + } + gc_type::scan(); + check_array( arr ); + } + + TEST_F( IntrusiveSPQueue_HP, base_hook ) + { + typedef cds::intrusive::SPQueue< gc_type, base_item_type, + typename ci::speculative_pairing_queue::make_traits< + ci::opt::disposer< mock_disposer > + ,ci::opt::hook< ci::speculative_pairing_queue::base_hook< ci::opt::gc>> + >::type + > test_queue; + + std::vector arr; + arr.resize(100); + { + test_queue q; + test(q, arr); + } + gc_type::scan(); + check_array( arr ); + } + + TEST_F( IntrusiveSPQueue_HP, base_item_counting ) + { + typedef cds::intrusive::SPQueue< gc_type, base_item_type, + typename ci::speculative_pairing_queue::make_traits< + ci::opt::disposer< mock_disposer > + , cds::opt::item_counter< cds::atomicity::item_counter > + , ci::opt::hook< ci::speculative_pairing_queue::base_hook< ci::opt::gc>> + >::type + > test_queue; + + std::vector arr; + arr.resize(100); + { + test_queue q; + test(q, arr); + } + gc_type::scan(); + check_array( arr ); + } + + TEST_F( IntrusiveSPQueue_HP, base_stat ) + { + struct traits : public ci::speculative_pairing_queue::traits + { + typedef mock_disposer disposer; + typedef cds::atomicity::item_counter item_counter; + typedef ci::speculative_pairing_queue::stat<> stat; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef cds::intrusive::SPQueue< gc_type, base_item_type, traits > test_queue; + + std::vector arr; + arr.resize(100); + { + test_queue q; + test(q, arr); + } + gc_type::scan(); + check_array( arr ); + } + + TEST_F( IntrusiveSPQueue_HP, member_hook ) + { + typedef cds::intrusive::SPQueue< gc_type, member_item_type, + typename ci::speculative_pairing_queue::make_traits< + ci::opt::disposer< mock_disposer > + ,ci::opt::hook< ci::speculative_pairing_queue::member_hook< + offsetof( member_item_type, hMember ), + ci::opt::gc + >> + >::type + > test_queue; + + std::vector arr; + arr.resize( 100 ); + { + test_queue q; + test( q, arr ); + } + gc_type::scan(); + check_array( arr ); + } + + TEST_F( IntrusiveSPQueue_HP, member_hook_stat ) + { + struct traits : public ci::speculative_pairing_queue::traits + { + typedef ci::speculative_pairing_queue::member_hook< + offsetof( member_item_type, hMember ), + ci::opt::gc + > hook; + typedef mock_disposer disposer; + typedef cds::atomicity::item_counter item_counter; + typedef ci::speculative_pairing_queue::stat<> stat; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef cds::intrusive::SPQueue< gc_type, member_item_type, traits > test_queue; + + std::vector arr; + arr.resize( 100 ); + { + test_queue q; + test( q, arr ); + } + gc_type::scan(); + check_array( arr ); + } + +} // namespace + diff --git a/test/unit/queue/speculative_pairing_queue_dhp.cpp b/test/unit/queue/speculative_pairing_queue_dhp.cpp new file mode 100644 index 000000000..815d0b719 --- /dev/null +++ b/test/unit/queue/speculative_pairing_queue_dhp.cpp @@ -0,0 +1,140 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "test_generic_queue.h" + +#include +#include + +namespace { + namespace cc = cds::container; + typedef cds::gc::DHP gc_type; + + + class SPQueue_DHP : public cds_test::generic_queue + { + protected: + void SetUp() + { + typedef cc::SPQueue< gc_type, int > queue_type; + + cds::gc::dhp::smr::construct( queue_type::c_nHazardPtrCount ); + cds::threading::Manager::attachThread(); + } + + void TearDown() + { + cds::threading::Manager::detachThread(); + cds::gc::dhp::smr::destruct(); + } + }; + + TEST_F( SPQueue_DHP, defaulted ) + { + typedef cds::container::SPQueue< gc_type, int > test_queue; + + test_queue q; + test(q); + } + + TEST_F( SPQueue_DHP, item_counting ) + { + typedef cds::container::SPQueue < gc_type, int, + typename cds::container::speculative_pairing_queue::make_traits < + cds::opt::item_counter < cds::atomicity::item_counter > + > ::type + > test_queue; + + test_queue q; + test( q ); + } + + TEST_F( SPQueue_DHP, relaxed ) + { + typedef cds::container::SPQueue < gc_type, int, + typename cds::container::speculative_pairing_queue::make_traits < + cds::opt::item_counter< cds::atomicity::item_counter > + , cds::opt::memory_model < cds::opt::v::relaxed_ordering > + > ::type + > test_queue; + + test_queue q; + test( q ); + } + + TEST_F( SPQueue_DHP, aligned ) + { + typedef cds::container::SPQueue < gc_type, int, + typename cds::container::speculative_pairing_queue::make_traits < + cds::opt::memory_model< cds::opt::v::relaxed_ordering> + , cds::opt::padding < 32 > + >::type + > test_queue; + + test_queue q; + test( q ); + } + + TEST_F( SPQueue_DHP, seq_cst ) + { + struct traits : public cc::speculative_pairing_queue::traits + { + typedef cds::opt::v::sequential_consistent memory_model; + typedef cds::atomicity::item_counter item_counter; + enum { padding = 64 }; + }; + typedef cds::container::SPQueue < gc_type, int, traits > test_queue; + + test_queue q; + test( q ); + } + + TEST_F( SPQueue_DHP, move ) + { + typedef cds::container::SPQueue< gc_type, std::string > test_queue; + + test_queue q; + test_string( q ); + } + + TEST_F( SPQueue_DHP, move_item_counting ) + { + struct traits : public cc::speculative_pairing_queue::traits + { + typedef cds::atomicity::item_counter item_counter; + }; + typedef cds::container::SPQueue< gc_type, std::string, traits > test_queue; + + test_queue q; + test_string( q ); + } + +} // namespace + diff --git a/test/unit/queue/speculative_pairing_queue_hp.cpp b/test/unit/queue/speculative_pairing_queue_hp.cpp new file mode 100644 index 000000000..98714c502 --- /dev/null +++ b/test/unit/queue/speculative_pairing_queue_hp.cpp @@ -0,0 +1,140 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "test_generic_queue.h" + +#include +#include + +namespace { + namespace cc = cds::container; + typedef cds::gc::HP gc_type; + + + class SPQueue_HP : public cds_test::generic_queue + { + protected: + void SetUp() + { + typedef cc::SPQueue< gc_type, int > queue_type; + + cds::gc::hp::GarbageCollector::Construct( queue_type::c_nHazardPtrCount, 1, 16 ); + cds::threading::Manager::attachThread(); + } + + void TearDown() + { + cds::threading::Manager::detachThread(); + cds::gc::hp::GarbageCollector::Destruct( true ); + } + }; + + TEST_F( SPQueue_HP, defaulted ) + { + typedef cds::container::SPQueue< gc_type, int > test_queue; + + test_queue q; + test(q); + } + + TEST_F( SPQueue_HP, item_counting ) + { + typedef cds::container::SPQueue < gc_type, int, + typename cds::container::speculative_pairing_queue::make_traits < + cds::opt::item_counter < cds::atomicity::item_counter > + > ::type + > test_queue; + + test_queue q; + test( q ); + } + + TEST_F( SPQueue_HP, relaxed ) + { + typedef cds::container::SPQueue < gc_type, int, + typename cds::container::speculative_pairing_queue::make_traits < + cds::opt::item_counter< cds::atomicity::item_counter > + , cds::opt::memory_model < cds::opt::v::relaxed_ordering > + > ::type + > test_queue; + + test_queue q; + test( q ); + } + + TEST_F( SPQueue_HP, aligned ) + { + typedef cds::container::SPQueue < gc_type, int, + typename cds::container::speculative_pairing_queue::make_traits < + cds::opt::memory_model< cds::opt::v::relaxed_ordering> + , cds::opt::padding < 32 > + >::type + > test_queue; + + test_queue q; + test( q ); + } + + TEST_F( SPQueue_HP, seq_cst ) + { + struct traits : public cc::speculative_pairing_queue::traits + { + typedef cds::opt::v::sequential_consistent memory_model; + typedef cds::atomicity::item_counter item_counter; + enum { padding = 64 }; + }; + typedef cds::container::SPQueue < gc_type, int, traits > test_queue; + + test_queue q; + test( q ); + } + + TEST_F( SPQueue_HP, move ) + { + typedef cds::container::SPQueue< gc_type, std::string > test_queue; + + test_queue q; + test_string( q ); + } + + TEST_F( SPQueue_HP, move_item_counting ) + { + struct traits : public cc::speculative_pairing_queue::traits + { + typedef cds::atomicity::item_counter item_counter; + }; + typedef cds::container::SPQueue< gc_type, std::string, traits > test_queue; + + test_queue q; + test_string( q ); + } + +} // namespace + diff --git a/test/unit/queue/test_intrusive_speculative_pairing_queue.h b/test/unit/queue/test_intrusive_speculative_pairing_queue.h new file mode 100644 index 000000000..ab8539985 --- /dev/null +++ b/test/unit/queue/test_intrusive_speculative_pairing_queue.h @@ -0,0 +1,201 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CDSUNIT_QUEUE_TEST_INTRUSIVE_SPECULATIVE_PAIRING_QUEUE_H +#define CDSUNIT_QUEUE_TEST_INTRUSIVE_SPECULATIVE_PAIRING_QUEUE_H + +#include + +namespace cds_test { + + class intrusive_speculative_pairing_queue : public ::testing::Test + { + protected: + template + struct base_hook_item : public Base + { + int nVal; + int nDisposeCount; + + base_hook_item() + : nDisposeCount( 0 ) + {} + + base_hook_item( base_hook_item const& s) + : nVal( s.nVal ) + , nDisposeCount( s.nDisposeCount ) + {} + }; + + template + struct member_hook_item + { + int nVal; + int nDisposeCount; + Member hMember; + + member_hook_item() + : nDisposeCount( 0 ) + {} + + member_hook_item( member_hook_item const& s ) + : nVal( s.nVal ) + , nDisposeCount( s.nDisposeCount ) + {} + }; + + struct mock_disposer + { + template + void operator ()( T * p ) + { + ++p->nDisposeCount; + } + }; + + template + void test( Queue& q, Data& arr ) + { + typedef typename Queue::value_type value_type; + size_t nSize = arr.size(); + + value_type * pv; + for ( size_t i = 0; i < nSize; ++i ) + arr[i].nVal = static_cast(i); + + //q.changeProbStale(0); + + pv = q.pop(); + ASSERT_TRUE( pv == nullptr ); + ASSERT_TRUE( q.empty()); + ASSERT_CONTAINER_SIZE( q, 0 ); + + pv = q.dequeue(); + ASSERT_TRUE( pv == nullptr ); + ASSERT_TRUE( q.empty()); + ASSERT_CONTAINER_SIZE( q, 0 ); + + // push/pop test + //------------------------------------ + for ( size_t i = 0; i < nSize; ++i ) { + if ( i & 1 ) + q.push( arr[i] ); + else + q.enqueue( arr[i] ); + ASSERT_FALSE( q.empty()); + ASSERT_CONTAINER_SIZE( q, i + 1 ); + } + + for ( size_t i = 0; i < nSize; ++i ) { + ASSERT_FALSE( q.empty()); + ASSERT_CONTAINER_SIZE( q, nSize - i ); + if ( i & 1 ) + pv = q.pop(); + else + pv = q.dequeue(); + ASSERT_FALSE( pv == nullptr ); + ASSERT_EQ( pv->nVal, static_cast(i)); + } + ASSERT_TRUE( q.empty()); + ASSERT_CONTAINER_SIZE( q, 0 ); + + //dispose queue and create new + q.clear(); + Queue::gc::scan(); + for ( size_t i = 0; i < nSize; ++i ) { + ASSERT_EQ( arr[i].nDisposeCount, 1 ) << "i=" << i; + } + //------------------------------------ + //end push/pop test + + //clear test + //------------------------------------ + for ( size_t i = 0; i < nSize; ++i ) + { + q.push( arr[i] ); + ASSERT_CONTAINER_SIZE( q, i+1); + } + + ASSERT_FALSE( q.empty()); + ASSERT_CONTAINER_SIZE( q, nSize); + q.clear(); + ASSERT_CONTAINER_SIZE( q, 0 ); + ASSERT_TRUE( q.empty()); + + Queue::gc::scan(); + for ( size_t i = 0; i < nSize; ++i ) { + ASSERT_EQ( arr[i].nDisposeCount, 2 ) << "i=" << i; + } + //------------------------------------ + //end clear test + + //clear stale nodes test + //------------------------------------ + //q.changeProbStale(100); + for ( size_t i = 0; i < nSize; ++i ) + { + q.push( arr[i] ); + ASSERT_CONTAINER_SIZE( q, i+1); + } + ASSERT_FALSE( q.empty()); + ASSERT_CONTAINER_SIZE( q, nSize); + + + for ( size_t i = 0; i < nSize; ++i ) { + ASSERT_FALSE( q.empty()); + ASSERT_CONTAINER_SIZE( q, nSize - i ); + if ( i & 1 ) + pv = q.pop(); + else + pv = q.dequeue(); + ASSERT_FALSE( pv == nullptr ); + ASSERT_EQ( pv->nVal, static_cast(i)); + } + + /* + //Queue::gc::scan(); + for ( size_t i = 0; i < nSize-20; ++i ) { + ASSERT_EQ( arr[i].nDisposeCount, 3 ) << "i=" << i; + } + for ( size_t i = nSize-20; i < nSize; ++i ) + { + ASSERT_EQ( arr[i].nDisposeCount, 2 ) << "i=" << i; + } + //------------------------------------ + //end clear stale nodes test + */ + + //clear queue + q.clear(); + Queue::gc::scan(); + for ( size_t i = 0; i < nSize; ++i ) { + ASSERT_EQ( arr[i].nDisposeCount, 3 ) << "i=" << i; + } + + } + }; + +} // namespace cds_test + +#endif // CDSUNIT_QUEUE_TEST_INTRUSIVE_MSQUEUE_H \ No newline at end of file From 6553bd1c561d80a987ed325dcebe816b582730ea Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Tue, 5 Feb 2019 20:33:47 +0300 Subject: [PATCH 02/26] Update intrusive_push_pop.cpp --- test/stress/queue/intrusive_push_pop.cpp | 34 +++--------------------- 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/test/stress/queue/intrusive_push_pop.cpp b/test/stress/queue/intrusive_push_pop.cpp index 9115bd22d..4c816f9dd 100644 --- a/test/stress/queue/intrusive_push_pop.cpp +++ b/test/stress/queue/intrusive_push_pop.cpp @@ -1,33 +1,7 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - +// Copyright (c) 2006-2018 Maxim Khizhinsky +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) #include "intrusive_queue_type.h" #include #include From e32fa3ff21cee140df51bdb9a745bea8cfa44009 Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Tue, 5 Feb 2019 20:34:32 +0300 Subject: [PATCH 03/26] Update intrusive_push_pop.cpp --- test/stress/queue/intrusive_push_pop.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/stress/queue/intrusive_push_pop.cpp b/test/stress/queue/intrusive_push_pop.cpp index 4c816f9dd..96c9d7753 100644 --- a/test/stress/queue/intrusive_push_pop.cpp +++ b/test/stress/queue/intrusive_push_pop.cpp @@ -1,6 +1,6 @@ -// Copyright (c) 2006-2018 Maxim Khizhinsky +// Copyright (c) 2006-2018 Maxim Khizhinsky // -// Distributed under the Boost Software License, Version 1.0. (See accompanying +// Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) #include "intrusive_queue_type.h" #include From 10f07cc40047b76a3d0fd72168e89bad47b62653 Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Tue, 5 Feb 2019 20:35:03 +0300 Subject: [PATCH 04/26] Update intrusive_push_pop.cpp --- test/stress/queue/intrusive_push_pop.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/stress/queue/intrusive_push_pop.cpp b/test/stress/queue/intrusive_push_pop.cpp index 96c9d7753..b3c6976e9 100644 --- a/test/stress/queue/intrusive_push_pop.cpp +++ b/test/stress/queue/intrusive_push_pop.cpp @@ -2,6 +2,7 @@ // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) + #include "intrusive_queue_type.h" #include #include From d6fc46e874320fef7e58aa6e9ecf477cf5e84a8d Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Tue, 5 Feb 2019 20:37:06 +0300 Subject: [PATCH 05/26] Update intrusive_queue_type.h --- test/stress/queue/intrusive_queue_type.h | 33 +++--------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/test/stress/queue/intrusive_queue_type.h b/test/stress/queue/intrusive_queue_type.h index 5142add72..76cff40c6 100644 --- a/test/stress/queue/intrusive_queue_type.h +++ b/test/stress/queue/intrusive_queue_type.h @@ -1,32 +1,7 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +// Copyright (c) 2006-2018 Maxim Khizhinsky +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef CDSSTRESS_INTRUSIVE_QUEUE_TYPES_H #define CDSSTRESS_INTRUSIVE_QUEUE_TYPES_H From 4beaf8e7299f65609674d3d2f993351ec9885aff Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Tue, 5 Feb 2019 20:37:50 +0300 Subject: [PATCH 06/26] Update pop.cpp --- test/stress/queue/pop.cpp | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/test/stress/queue/pop.cpp b/test/stress/queue/pop.cpp index 379449ebd..287ccbb4a 100644 --- a/test/stress/queue/pop.cpp +++ b/test/stress/queue/pop.cpp @@ -1,32 +1,7 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +// Copyright (c) 2006-2018 Maxim Khizhinsky +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) #include "queue_type.h" From 4f771942b21707d1a341d19dace10cb89ed3e7d5 Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Tue, 5 Feb 2019 20:38:32 +0300 Subject: [PATCH 07/26] Update print_stat.h --- test/stress/queue/print_stat.h | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/test/stress/queue/print_stat.h b/test/stress/queue/print_stat.h index d64aa810d..8e1d8fc29 100644 --- a/test/stress/queue/print_stat.h +++ b/test/stress/queue/print_stat.h @@ -1,32 +1,7 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +// Copyright (c) 2006-2018 Maxim Khizhinsky +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef CDSSTRESS_QUEUE_PRINT_STAT_H #define CDSSTRESS_QUEUE_PRINT_STAT_H From f4f3b899aa18178751e572375fbedb6e5ebcf368 Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Tue, 5 Feb 2019 20:39:20 +0300 Subject: [PATCH 08/26] Update push.cpp --- test/stress/queue/push.cpp | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/test/stress/queue/push.cpp b/test/stress/queue/push.cpp index 1f1304cc8..d7fd78986 100644 --- a/test/stress/queue/push.cpp +++ b/test/stress/queue/push.cpp @@ -1,32 +1,7 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +// Copyright (c) 2006-2018 Maxim Khizhinsky +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) #include "queue_type.h" From 0d6313a4b3d380a90abccce1eaaff966b1f9b57e Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Tue, 5 Feb 2019 20:40:28 +0300 Subject: [PATCH 09/26] Update spsc_buffer.cpp --- test/stress/queue/spsc_buffer.cpp | 33 ++++--------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/test/stress/queue/spsc_buffer.cpp b/test/stress/queue/spsc_buffer.cpp index 37402543c..458708f76 100644 --- a/test/stress/queue/spsc_buffer.cpp +++ b/test/stress/queue/spsc_buffer.cpp @@ -1,32 +1,7 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +// Copyright (c) 2006-2018 Maxim Khizhinsky +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) #include "queue_type.h" From efeaccf3ce4ec3ec63a314a1f95284c62931b3ee Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Tue, 5 Feb 2019 20:41:13 +0300 Subject: [PATCH 10/26] Update random.cpp --- test/stress/queue/random.cpp | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/test/stress/queue/random.cpp b/test/stress/queue/random.cpp index 27e767d9f..ac49edf20 100644 --- a/test/stress/queue/random.cpp +++ b/test/stress/queue/random.cpp @@ -1,32 +1,7 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +// Copyright (c) 2006-2018 Maxim Khizhinsky +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) #include "queue_type.h" From dfa9b9646e37fd40ebc6d0d4a6edbc1969f10a72 Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Tue, 5 Feb 2019 20:42:05 +0300 Subject: [PATCH 11/26] Update queue_type.h --- test/stress/queue/queue_type.h | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/test/stress/queue/queue_type.h b/test/stress/queue/queue_type.h index c452cac71..c146a9fd9 100644 --- a/test/stress/queue/queue_type.h +++ b/test/stress/queue/queue_type.h @@ -1,32 +1,7 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +// Copyright (c) 2006-2018 Maxim Khizhinsky +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef CDSSTRESS_QUEUE_TYPES_H #define CDSSTRESS_QUEUE_TYPES_H From e8c093b5031e032a8a669ad2b20fe1cbfbc0ef3b Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Tue, 5 Feb 2019 20:42:54 +0300 Subject: [PATCH 12/26] Update push_pop.cpp --- test/stress/queue/push_pop.cpp | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/test/stress/queue/push_pop.cpp b/test/stress/queue/push_pop.cpp index 280d35c40..d1ed31769 100644 --- a/test/stress/queue/push_pop.cpp +++ b/test/stress/queue/push_pop.cpp @@ -1,32 +1,7 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +// Copyright (c) 2006-2018 Maxim Khizhinsky +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) #include "queue_type.h" From d2a9bda9c98f0b70a6ae94022a4921316c5353d8 Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Wed, 6 Feb 2019 07:41:49 +0300 Subject: [PATCH 13/26] Update speculative_pairing_queue.h --- cds/intrusive/speculative_pairing_queue.h | 82 +---------------------- 1 file changed, 1 insertion(+), 81 deletions(-) diff --git a/cds/intrusive/speculative_pairing_queue.h b/cds/intrusive/speculative_pairing_queue.h index f9d1bc246..912899b2b 100644 --- a/cds/intrusive/speculative_pairing_queue.h +++ b/cds/intrusive/speculative_pairing_queue.h @@ -32,11 +32,6 @@ #include #include -//#include -//#include -//#include -//#include - #include #include #include @@ -85,31 +80,6 @@ namespace cds { namespace intrusive { void onCloseQueue() { ++m_nClosingQueue ;} //@endcond - //@cond - /*void reset() - { - m_EnqueueCount.reset(); - m_DequeueCount.reset(); - m_EnqueueRace.reset(); - m_DequeueRace.reset(); - m_AdvanceTailError.reset(); - m_BadTail.reset(); - m_EmptyDequeue.reset(); - } - - stat& operator +=(stat const& s) - { - m_EnqueueCount += s.m_EnqueueCount.get(); - m_DequeueCount += s.m_DequeueCount.get(); - m_EnqueueRace += s.m_EnqueueRace.get(); - m_DequeueRace += s.m_DequeueRace.get(); - m_AdvanceTailError += s.m_AdvanceTailError.get(); - m_BadTail += s.m_BadTail.get(); - m_EmptyDequeue += s.m_EmptyDequeue.get(); - - return *this; - }*/ - //@endcond }; /// MSPriorityQueue empty statistics @@ -341,48 +311,6 @@ namespace cds { namespace intrusive { gc::template retire(queue); } -/* void dispose_stale_nodes( Slot &slot){ - boost::mt19937 gen; - boost::uniform_int<> dist(0,99); - boost::variate_generator > roll(gen, dist); - - int random_int = roll(); - //EXPECT_TRUE(false) << "lol"; - if (random_int < probStale) - { - - typename gc::template Guard node_guard; - typename std::list stale_nodes; - node_type* head = node_guard.protect(slot.m_pHead); - node_type* curr = head; - node_type* last = curr; - //EXPECT_TRUE(false) << "head" << node_traits::to_value_ptr(head->m_pNext)->nVal; - - while (curr != nullptr && curr->m_removed){ - //if (current_node != PICKET) - stale_nodes.push_back(curr); - curr = node_guard.protect(curr->m_pNext); - } - - if (stale_nodes.size() > 0) - { - if (slot.m_pHead.compare_exchange_strong(head, - last, - memory_model::memory_order_relaxed, - memory_model::memory_order_relaxed)){ - stale_nodes.pop_back(); - - for (typename std::list::iterator it = stale_nodes.begin(); it != stale_nodes.end(); it++){ - //EXPECT_TRUE(false) << "Dis stale" << node_traits::to_value_ptr(*it)->nVal; - dispose_node(*it); - } - } - } - - } - } -*/ - public: /// Constructs empty speculative pairing queue /** @@ -548,19 +476,12 @@ namespace cds { namespace intrusive { } - size_t ticket = pQueue->m_Cntdeq++;//.fetch_add(1, memory_model::memory_order_seq_cst); - /*====== ТОТ САМЫЙ ВЫВОД TICKET =====*/ - //std::string s = std::to_string(ticket) + "\n"; - //std::cerr << s; + size_t ticket = pQueue->m_Cntdeq++; size_t idx = ticket % C_SIZE; guards.protect(0, pQueue->m_pair[idx].m_pRemoved); guards.protect(1, pQueue->m_pair[idx].m_pHead); - //dispose_stale_nodes(pQueue->m_pair[idx]); - - //guards.protect(1, pQueue->m_pair[idx].m_pHead); - if (ticket >= pQueue->m_Tail.load(memory_model::memory_order_acquire) && ticket == idx) {//Error in article. may be must be >= node_type* DUMMY = nullptr; if (pQueue->m_pair[idx].m_pHead.compare_exchange_strong(DUMMY, PICKET, memory_model::memory_order_seq_cst,memory_model::memory_order_acquire)) { @@ -602,7 +523,6 @@ namespace cds { namespace intrusive { value_type* x = node_traits::to_value_ptr(pNode); pQueue->m_pair[idx].m_pRemoved.store(pNode, memory_model::memory_order_release); - //pNode->m_removed = true; --m_ItemCounter; m_Stat.onDequeSuccess(); return x; From 3569f3c578e1355de95d25f35bf6559665970ec3 Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Wed, 6 Feb 2019 07:56:55 +0300 Subject: [PATCH 14/26] Update push.cpp --- test/stress/queue/push.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/test/stress/queue/push.cpp b/test/stress/queue/push.cpp index d7fd78986..854a3f706 100644 --- a/test/stress/queue/push.cpp +++ b/test/stress/queue/push.cpp @@ -60,7 +60,6 @@ namespace { if ( !m_Queue.push( nItem )) { ++m_nPushError; } - //EXPECT_TRUE(false) << "nItem = " << nItem; } } From 74c4ffd7e7049da4a979047104660b19ceab7f40 Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Wed, 6 Feb 2019 08:07:57 +0300 Subject: [PATCH 15/26] Update test_intrusive_speculative_pairing_queue.h --- ...test_intrusive_speculative_pairing_queue.h | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/test/unit/queue/test_intrusive_speculative_pairing_queue.h b/test/unit/queue/test_intrusive_speculative_pairing_queue.h index ab8539985..884c3d12e 100644 --- a/test/unit/queue/test_intrusive_speculative_pairing_queue.h +++ b/test/unit/queue/test_intrusive_speculative_pairing_queue.h @@ -84,8 +84,6 @@ namespace cds_test { for ( size_t i = 0; i < nSize; ++i ) arr[i].nVal = static_cast(i); - //q.changeProbStale(0); - pv = q.pop(); ASSERT_TRUE( pv == nullptr ); ASSERT_TRUE( q.empty()); @@ -152,7 +150,6 @@ namespace cds_test { //clear stale nodes test //------------------------------------ - //q.changeProbStale(100); for ( size_t i = 0; i < nSize; ++i ) { q.push( arr[i] ); @@ -171,21 +168,7 @@ namespace cds_test { pv = q.dequeue(); ASSERT_FALSE( pv == nullptr ); ASSERT_EQ( pv->nVal, static_cast(i)); - } - - /* - //Queue::gc::scan(); - for ( size_t i = 0; i < nSize-20; ++i ) { - ASSERT_EQ( arr[i].nDisposeCount, 3 ) << "i=" << i; - } - for ( size_t i = nSize-20; i < nSize; ++i ) - { - ASSERT_EQ( arr[i].nDisposeCount, 2 ) << "i=" << i; - } - //------------------------------------ - //end clear stale nodes test - */ - + } //clear queue q.clear(); Queue::gc::scan(); @@ -198,4 +181,4 @@ namespace cds_test { } // namespace cds_test -#endif // CDSUNIT_QUEUE_TEST_INTRUSIVE_MSQUEUE_H \ No newline at end of file +#endif // CDSUNIT_QUEUE_TEST_INTRUSIVE_MSQUEUE_H From 9cded93498dbe2c12931f4cae905fcf509d475e9 Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Wed, 6 Feb 2019 08:13:40 +0300 Subject: [PATCH 16/26] Update speculative_pairing_queue.h --- cds/container/speculative_pairing_queue.h | 33 +++-------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/cds/container/speculative_pairing_queue.h b/cds/container/speculative_pairing_queue.h index e6bbc1386..365b0a143 100644 --- a/cds/container/speculative_pairing_queue.h +++ b/cds/container/speculative_pairing_queue.h @@ -1,32 +1,7 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +// Copyright (c) 2006-2018 Maxim Khizhinsky +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef CDSLIB_CONTAINER_SPECULATIVE_PAIRING_QUEUE_H #define CDSLIB_CONTAINER_SPECULATIVE_PAIRING_QUEUE_H From 230858563d7552287d468bb1511a046366c9b455 Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Wed, 6 Feb 2019 08:14:13 +0300 Subject: [PATCH 17/26] Update sp_queue_base.h --- cds/intrusive/details/sp_queue_base.h | 33 ++++----------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/cds/intrusive/details/sp_queue_base.h b/cds/intrusive/details/sp_queue_base.h index e53627d8c..ac6229e11 100644 --- a/cds/intrusive/details/sp_queue_base.h +++ b/cds/intrusive/details/sp_queue_base.h @@ -1,32 +1,7 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +// Copyright (c) 2006-2018 Maxim Khizhinsky +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef CDSLIB_INTRUSIVE_DETAILS_SP_QUEUE_BASE_H #define CDSLIB_INTRUSIVE_DETAILS_SP_QUEUE_BASE_H From 55b6b4849382857f56994cf8713e82e30e748d5b Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Wed, 6 Feb 2019 08:14:54 +0300 Subject: [PATCH 18/26] Update speculative_pairing_queue.h --- cds/intrusive/speculative_pairing_queue.h | 27 ++++------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/cds/intrusive/speculative_pairing_queue.h b/cds/intrusive/speculative_pairing_queue.h index 912899b2b..f347597df 100644 --- a/cds/intrusive/speculative_pairing_queue.h +++ b/cds/intrusive/speculative_pairing_queue.h @@ -1,26 +1,7 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +// Copyright (c) 2006-2018 Maxim Khizhinsky +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef CDSLIB_INTRUSIVE_SPECULATIVE_PAIRING_QUEUE_H #define CDSLIB_INTRUSIVE_SPECULATIVE_PAIRING_QUEUE_H From c7be8fb89c09f1ca84627443f0910851e00fc077 Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Wed, 6 Feb 2019 08:18:24 +0300 Subject: [PATCH 19/26] Update intrusive_speculative_pairing_queue_dhp.cpp --- ...ntrusive_speculative_pairing_queue_dhp.cpp | 27 +++---------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/test/unit/queue/intrusive_speculative_pairing_queue_dhp.cpp b/test/unit/queue/intrusive_speculative_pairing_queue_dhp.cpp index 6a70fcec4..4df095f97 100644 --- a/test/unit/queue/intrusive_speculative_pairing_queue_dhp.cpp +++ b/test/unit/queue/intrusive_speculative_pairing_queue_dhp.cpp @@ -1,26 +1,7 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +// Copyright (c) 2006-2018 Maxim Khizhinsky +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) #include "test_intrusive_speculative_pairing_queue.h" From d930350f1b14b3236fb1de65f4cf9ca17a709604 Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Wed, 6 Feb 2019 08:19:10 +0300 Subject: [PATCH 20/26] Update intrusive_speculative_pairing_queue_hp.cpp --- ...intrusive_speculative_pairing_queue_hp.cpp | 33 +++---------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/test/unit/queue/intrusive_speculative_pairing_queue_hp.cpp b/test/unit/queue/intrusive_speculative_pairing_queue_hp.cpp index b2f52dfc3..5839ff074 100644 --- a/test/unit/queue/intrusive_speculative_pairing_queue_hp.cpp +++ b/test/unit/queue/intrusive_speculative_pairing_queue_hp.cpp @@ -1,32 +1,7 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +// Copyright (c) 2006-2018 Maxim Khizhinsky +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) #include "test_intrusive_speculative_pairing_queue.h" From 818afe4649dfbc2a3bed9d9a53be39e41fa6d8ec Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Wed, 6 Feb 2019 08:19:58 +0300 Subject: [PATCH 21/26] Update speculative_pairing_queue_dhp.cpp --- .../queue/speculative_pairing_queue_dhp.cpp | 33 +++---------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/test/unit/queue/speculative_pairing_queue_dhp.cpp b/test/unit/queue/speculative_pairing_queue_dhp.cpp index 815d0b719..d1f47d04a 100644 --- a/test/unit/queue/speculative_pairing_queue_dhp.cpp +++ b/test/unit/queue/speculative_pairing_queue_dhp.cpp @@ -1,32 +1,7 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +// Copyright (c) 2006-2018 Maxim Khizhinsky +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) #include "test_generic_queue.h" From b2f39313528417ec7cdc3233d05f6ca8ab9d9591 Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Wed, 6 Feb 2019 08:20:41 +0300 Subject: [PATCH 22/26] Update speculative_pairing_queue_hp.cpp --- .../queue/speculative_pairing_queue_hp.cpp | 33 +++---------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/test/unit/queue/speculative_pairing_queue_hp.cpp b/test/unit/queue/speculative_pairing_queue_hp.cpp index 98714c502..fb9d6d64b 100644 --- a/test/unit/queue/speculative_pairing_queue_hp.cpp +++ b/test/unit/queue/speculative_pairing_queue_hp.cpp @@ -1,32 +1,7 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +// Copyright (c) 2006-2018 Maxim Khizhinsky +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) #include "test_generic_queue.h" From 1fc589e7a8b2c38a416a581241370462ba1db19d Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Wed, 6 Feb 2019 08:21:55 +0300 Subject: [PATCH 23/26] Update test_intrusive_speculative_pairing_queue.h --- ...test_intrusive_speculative_pairing_queue.h | 27 +++---------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/test/unit/queue/test_intrusive_speculative_pairing_queue.h b/test/unit/queue/test_intrusive_speculative_pairing_queue.h index 884c3d12e..781c9639d 100644 --- a/test/unit/queue/test_intrusive_speculative_pairing_queue.h +++ b/test/unit/queue/test_intrusive_speculative_pairing_queue.h @@ -1,26 +1,7 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +// Copyright (c) 2006-2018 Maxim Khizhinsky +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef CDSUNIT_QUEUE_TEST_INTRUSIVE_SPECULATIVE_PAIRING_QUEUE_H #define CDSUNIT_QUEUE_TEST_INTRUSIVE_SPECULATIVE_PAIRING_QUEUE_H From 0ff5393b6325840d5d128e8ba5f6aa71c2460801 Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Wed, 6 Feb 2019 09:36:58 +0300 Subject: [PATCH 24/26] Update test_intrusive_speculative_pairing_queue.h --- ...test_intrusive_speculative_pairing_queue.h | 48 +++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/test/unit/queue/test_intrusive_speculative_pairing_queue.h b/test/unit/queue/test_intrusive_speculative_pairing_queue.h index 781c9639d..e056a8a23 100644 --- a/test/unit/queue/test_intrusive_speculative_pairing_queue.h +++ b/test/unit/queue/test_intrusive_speculative_pairing_queue.h @@ -81,7 +81,7 @@ namespace cds_test { if ( i & 1 ) q.push( arr[i] ); else - q.enqueue( arr[i] ); + q.enqueue( arr[i] ); ASSERT_FALSE( q.empty()); ASSERT_CONTAINER_SIZE( q, i + 1 ); } @@ -99,22 +99,22 @@ namespace cds_test { ASSERT_TRUE( q.empty()); ASSERT_CONTAINER_SIZE( q, 0 ); - //dispose queue and create new - q.clear(); + //dispose queue and create new + q.clear(); Queue::gc::scan(); for ( size_t i = 0; i < nSize; ++i ) { ASSERT_EQ( arr[i].nDisposeCount, 1 ) << "i=" << i; } //------------------------------------ - //end push/pop test + //end push/pop test //clear test - //------------------------------------ - for ( size_t i = 0; i < nSize; ++i ) + //------------------------------------ + for ( size_t i = 0; i < nSize; ++i ) { q.push( arr[i] ); - ASSERT_CONTAINER_SIZE( q, i+1); - } + ASSERT_CONTAINER_SIZE( q, i+1); + } ASSERT_FALSE( q.empty()); ASSERT_CONTAINER_SIZE( q, nSize); @@ -122,25 +122,24 @@ namespace cds_test { ASSERT_CONTAINER_SIZE( q, 0 ); ASSERT_TRUE( q.empty()); - Queue::gc::scan(); + Queue::gc::scan(); for ( size_t i = 0; i < nSize; ++i ) { ASSERT_EQ( arr[i].nDisposeCount, 2 ) << "i=" << i; } - //------------------------------------ - //end clear test + //------------------------------------ + //end clear test - //clear stale nodes test - //------------------------------------ - for ( size_t i = 0; i < nSize; ++i ) + //clear stale nodes test + //------------------------------------ + for ( size_t i = 0; i < nSize; ++i ) { q.push( arr[i] ); - ASSERT_CONTAINER_SIZE( q, i+1); - } - ASSERT_FALSE( q.empty()); + ASSERT_CONTAINER_SIZE( q, i+1); + } + ASSERT_FALSE( q.empty()); ASSERT_CONTAINER_SIZE( q, nSize); - - - for ( size_t i = 0; i < nSize; ++i ) { + + for ( size_t i = 0; i < nSize; ++i ) { ASSERT_FALSE( q.empty()); ASSERT_CONTAINER_SIZE( q, nSize - i ); if ( i & 1 ) @@ -150,13 +149,12 @@ namespace cds_test { ASSERT_FALSE( pv == nullptr ); ASSERT_EQ( pv->nVal, static_cast(i)); } - //clear queue - q.clear(); - Queue::gc::scan(); + //clear queue + q.clear(); + Queue::gc::scan(); for ( size_t i = 0; i < nSize; ++i ) { ASSERT_EQ( arr[i].nDisposeCount, 3 ) << "i=" << i; - } - + } } }; From f2075dcdfbda153f456f9de261a621b8420e38a7 Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Wed, 6 Feb 2019 09:48:26 +0300 Subject: [PATCH 25/26] Update spsc_buffer.cpp --- test/stress/queue/spsc_buffer.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/stress/queue/spsc_buffer.cpp b/test/stress/queue/spsc_buffer.cpp index 458708f76..28ef9d084 100644 --- a/test/stress/queue/spsc_buffer.cpp +++ b/test/stress/queue/spsc_buffer.cpp @@ -105,11 +105,11 @@ namespace { } public: - Queue& m_Queue; - size_t m_nPushFailed = 0; - size_t m_nPushed = 0; + Queue& m_Queue; + size_t m_nPushFailed = 0; + size_t m_nPushed = 0; - double m_PayloadResult = 0.0; + double m_PayloadResult = 0.0; }; template @@ -119,13 +119,13 @@ namespace { typedef Payload payload_type; public: - Queue& m_Queue; - size_t m_nPopEmpty = 0; - size_t m_nPopped = 0; - size_t m_nBadValue = 0; - size_t m_nPopFrontFailed = 0; + Queue& m_Queue; + size_t m_nPopEmpty = 0; + size_t m_nPopped = 0; + size_t m_nBadValue = 0; + size_t m_nPopFrontFailed = 0; - double m_PayloadResult = 0.0; + double m_PayloadResult = 0.0; public: Consumer( cds_test::thread_pool& pool, Queue& queue ) From 1d3edecbc3fb683196f9fccd02f40c4cb31cfd79 Mon Sep 17 00:00:00 2001 From: Kompanishchenko Nikita Date: Wed, 6 Feb 2019 09:55:42 +0300 Subject: [PATCH 26/26] Update spsc_buffer.cpp --- test/stress/queue/spsc_buffer.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/stress/queue/spsc_buffer.cpp b/test/stress/queue/spsc_buffer.cpp index 28ef9d084..c707ad2c0 100644 --- a/test/stress/queue/spsc_buffer.cpp +++ b/test/stress/queue/spsc_buffer.cpp @@ -46,9 +46,9 @@ namespace { void operator()() { std::random_device rd; - std::mt19937 gen( rd() ); + std::mt19937 gen( rd()); std::uniform_int_distribution dis( 0, 64 * 1024* 1024 ); - quad_sum += std::sqrt( static_cast( dis(gen) )); + quad_sum += std::sqrt( static_cast( dis(gen))); } double result() @@ -105,11 +105,11 @@ namespace { } public: - Queue& m_Queue; - size_t m_nPushFailed = 0; - size_t m_nPushed = 0; + Queue& m_Queue; + size_t m_nPushFailed = 0; + size_t m_nPushed = 0; - double m_PayloadResult = 0.0; + double m_PayloadResult = 0.0; }; template @@ -119,13 +119,13 @@ namespace { typedef Payload payload_type; public: - Queue& m_Queue; - size_t m_nPopEmpty = 0; - size_t m_nPopped = 0; - size_t m_nBadValue = 0; - size_t m_nPopFrontFailed = 0; + Queue& m_Queue; + size_t m_nPopEmpty = 0; + size_t m_nPopped = 0; + size_t m_nBadValue = 0; + size_t m_nPopFrontFailed = 0; - double m_PayloadResult = 0.0; + double m_PayloadResult = 0.0; public: Consumer( cds_test::thread_pool& pool, Queue& queue )