From 940c036c576d3c047b0e582bae3a91112c6fdac1 Mon Sep 17 00:00:00 2001
From: khizmax <libcds.dev@gmail.com>
Date: Tue, 7 Oct 2014 08:58:26 +0400
Subject: [PATCH] MSQueue, MoirQueue refactoring done (issues #1, #2, #3)

---
 cds/container/moir_queue.h                  |  4 +-
 cds/container/msqueue.h                     |  5 +-
 cds/intrusive/msqueue.h                     | 24 +++---
 tests/test-hdr/queue/hdr_queue.h            | 88 ---------------------
 tests/test-hdr/queue/hdr_queue_register.cpp | 10 +--
 tests/unit/queue/intrusive_queue_type.h     | 18 +++++
 tests/unit/queue/queue_type.h               | 20 ++++-
 7 files changed, 60 insertions(+), 109 deletions(-)

diff --git a/cds/container/moir_queue.h b/cds/container/moir_queue.h
index 832e5c9d..969656f8 100644
--- a/cds/container/moir_queue.h
+++ b/cds/container/moir_queue.h
@@ -15,7 +15,7 @@ namespace cds { namespace container {
         struct make_moir_queue: public cds::container::details::make_msqueue< GC, T, Traits >
         {
             typedef cds::container::details::make_msqueue< GC, T, Traits > base_class;
-            typedef cds::intrusive::MoirQueue< GC, base_class::node_type, base_class::intrusive_traits > type;
+            typedef cds::intrusive::MoirQueue< GC, typename base_class::node_type, typename base_class::intrusive_traits > type;
         };
     }
     //@endcond
@@ -45,7 +45,7 @@ namespace cds { namespace container {
             > myQueue;
             \endcode
     */
-    template <typename GC, typename T, typename Traits>
+    template <typename GC, typename T, typename Traits = cds::container::msqueue::traits >
     class MoirQueue:
 #ifdef CDS_DOXYGEN_INVOKED
         private intrusive::MoirQueue< GC, intrusive::msqueue::node< T >, Traits >
diff --git a/cds/container/msqueue.h b/cds/container/msqueue.h
index df6a5773..94e589c2 100644
--- a/cds/container/msqueue.h
+++ b/cds/container/msqueue.h
@@ -124,8 +124,9 @@ namespace cds { namespace container {
 
             struct intrusive_traits : public traits
             {
-                typedef cds::intrusive::base_hook< cds::opt::gc<gc> > hook;
+                typedef cds::intrusive::msqueue::base_hook< cds::opt::gc<gc> > hook;
                 typedef node_deallocator disposer;
+                static CDS_CONSTEXPR const cds::intrusive::opt::link_check_type link_checker = cds::intrusive::msqueue::traits::link_checker;
             };
 
             typedef intrusive::MSQueue< gc, node_type, intrusive_traits > type;
@@ -159,7 +160,7 @@ namespace cds { namespace container {
             > myQueue;
             \endcode
     */
-    template <typename GC, typename T, typename Traits = msqueue::traits>
+    template <typename GC, typename T, typename Traits = cds::container::msqueue::traits>
     class MSQueue:
 #ifdef CDS_DOXYGEN_INVOKED
         private intrusive::MSQueue< GC, cds::intrusive::msqueue::node< T >, Traits >
diff --git a/cds/intrusive/msqueue.h b/cds/intrusive/msqueue.h
index 9a81f3a0..972ff808 100644
--- a/cds/intrusive/msqueue.h
+++ b/cds/intrusive/msqueue.h
@@ -165,7 +165,7 @@ namespace cds { namespace intrusive {
             typedef opt::v::relaxed_ordering    memory_model;
 
             /// Link checking, see \p cds::opt::link_checker
-            static const opt::link_check_type link_checker = opt::debug_check_link;
+            static CDS_CONSTEXPR const opt::link_check_type link_checker = opt::debug_check_link;
 
             /// Alignment of internal queue data. Default is \p opt::cache_line_alignment
             enum { alignment = opt::cache_line_alignment };
@@ -418,15 +418,18 @@ namespace cds { namespace intrusive {
             // HP retiring cycle since m_Dummy is member of MSQueue and may be destroyed
             // before HP retiring cycle invocation.
             // So, we will never clear m_Dummy
-            if ( p != &m_Dummy ) {
-                gc::retire( node_traits::to_value_ptr(p),
-                    []( value_type * ptr ) {
-                        assert( ptr != nullptr );
-                        MSQueue::clear_links( node_traits::to_node_ptr( ptr ) );
-                        disposer()(ptr);
-                    }
-                );
-            }
+
+            struct disposer_thunk {
+                void operator()( value_type * p ) const
+                {
+                    assert( p != nullptr );
+                    MSQueue::clear_links( node_traits::to_node_ptr( p ) );
+                    disposer()(p);
+                }
+            };
+
+            if ( p != &m_Dummy )
+                gc::template retire<disposer_thunk>( node_traits::to_value_ptr( p ) );
         }
         //@endcond
 
@@ -580,7 +583,6 @@ namespace cds { namespace intrusive {
         {
             return m_Stat;
         }
-
     };
 
 }} // namespace cds::intrusive
diff --git a/tests/test-hdr/queue/hdr_queue.h b/tests/test-hdr/queue/hdr_queue.h
index 2023d420..c48db253 100644
--- a/tests/test-hdr/queue/hdr_queue.h
+++ b/tests/test-hdr/queue/hdr_queue.h
@@ -139,50 +139,6 @@ namespace queue {
         }
 
     public:
-        void MSQueue_HP();
-        void MSQueue_HP_relax();
-        void MSQueue_HP_seqcst();
-        void MSQueue_HP_relax_align();
-        void MSQueue_HP_seqcst_align();
-        void MSQueue_HP_Counted();
-        void MSQueue_HP_Counted_relax();
-        void MSQueue_HP_Counted_seqcst();
-        void MSQueue_HP_Counted_relax_align();
-        void MSQueue_HP_Counted_seqcst_align();
-
-        void MSQueue_DHP();
-        void MSQueue_DHP_relax();
-        void MSQueue_DHP_seqcst();
-        void MSQueue_DHP_relax_align();
-        void MSQueue_DHP_seqcst_align();
-        void MSQueue_DHP_Counted();
-        void MSQueue_DHP_Counted_relax();
-        void MSQueue_DHP_Counted_seqcst();
-        void MSQueue_DHP_Counted_relax_align();
-        void MSQueue_DHP_Counted_seqcst_align();
-
-        void MoirQueue_HP();
-        void MoirQueue_HP_relax();
-        void MoirQueue_HP_seqcst();
-        void MoirQueue_HP_relax_align();
-        void MoirQueue_HP_seqcst_align();
-        void MoirQueue_HP_Counted();
-        void MoirQueue_HP_Counted_relax();
-        void MoirQueue_HP_Counted_seqcst();
-        void MoirQueue_HP_Counted_relax_align();
-        void MoirQueue_HP_Counted_seqcst_align();
-
-        void MoirQueue_DHP();
-        void MoirQueue_DHP_relax();
-        void MoirQueue_DHP_seqcst();
-        void MoirQueue_DHP_relax_align();
-        void MoirQueue_DHP_seqcst_align();
-        void MoirQueue_DHP_Counted();
-        void MoirQueue_DHP_Counted_relax();
-        void MoirQueue_DHP_Counted_seqcst();
-        void MoirQueue_DHP_Counted_relax_align();
-        void MoirQueue_DHP_Counted_seqcst_align();
-
         void OptimisticQueue_HP();
         void OptimisticQueue_HP_relax();
         void OptimisticQueue_HP_seqcst();
@@ -254,50 +210,6 @@ namespace queue {
         void RWQueue_Counted();
 
         CPPUNIT_TEST_SUITE(Queue_TestHeader)
-            CPPUNIT_TEST(MSQueue_HP);
-            CPPUNIT_TEST(MSQueue_HP_relax);
-            CPPUNIT_TEST(MSQueue_HP_seqcst);
-            CPPUNIT_TEST(MSQueue_HP_relax_align);
-            CPPUNIT_TEST(MSQueue_HP_seqcst_align);
-            CPPUNIT_TEST(MSQueue_HP_Counted);
-            CPPUNIT_TEST(MSQueue_HP_Counted_relax);
-            CPPUNIT_TEST(MSQueue_HP_Counted_seqcst);
-            CPPUNIT_TEST(MSQueue_HP_Counted_relax_align);
-            CPPUNIT_TEST(MSQueue_HP_Counted_seqcst_align);
-
-            CPPUNIT_TEST(MSQueue_DHP);
-            CPPUNIT_TEST(MSQueue_DHP_relax);
-            CPPUNIT_TEST(MSQueue_DHP_seqcst);
-            CPPUNIT_TEST(MSQueue_DHP_relax_align);
-            CPPUNIT_TEST(MSQueue_DHP_seqcst_align);
-            CPPUNIT_TEST(MSQueue_DHP_Counted);
-            CPPUNIT_TEST(MSQueue_DHP_Counted_relax);
-            CPPUNIT_TEST(MSQueue_DHP_Counted_seqcst);
-            CPPUNIT_TEST(MSQueue_DHP_Counted_relax_align);
-            CPPUNIT_TEST(MSQueue_DHP_Counted_seqcst_align);
-
-            CPPUNIT_TEST(MoirQueue_HP);
-            CPPUNIT_TEST(MoirQueue_HP_relax);
-            CPPUNIT_TEST(MoirQueue_HP_seqcst);
-            CPPUNIT_TEST(MoirQueue_HP_relax_align);
-            CPPUNIT_TEST(MoirQueue_HP_seqcst_align);
-            CPPUNIT_TEST(MoirQueue_HP_Counted);
-            CPPUNIT_TEST(MoirQueue_HP_Counted_relax);
-            CPPUNIT_TEST(MoirQueue_HP_Counted_seqcst);
-            CPPUNIT_TEST(MoirQueue_HP_Counted_relax_align);
-            CPPUNIT_TEST(MoirQueue_HP_Counted_seqcst_align);
-
-            CPPUNIT_TEST(MoirQueue_DHP);
-            CPPUNIT_TEST(MoirQueue_DHP_relax);
-            CPPUNIT_TEST(MoirQueue_DHP_seqcst);
-            CPPUNIT_TEST(MoirQueue_DHP_relax_align);
-            CPPUNIT_TEST(MoirQueue_DHP_seqcst_align);
-            CPPUNIT_TEST(MoirQueue_DHP_Counted);
-            CPPUNIT_TEST(MoirQueue_DHP_Counted_relax);
-            CPPUNIT_TEST(MoirQueue_DHP_Counted_seqcst);
-            CPPUNIT_TEST(MoirQueue_DHP_Counted_relax_align);
-            CPPUNIT_TEST(MoirQueue_DHP_Counted_seqcst_align);
-
             CPPUNIT_TEST(OptimisticQueue_HP);
             CPPUNIT_TEST(OptimisticQueue_HP_relax);
             CPPUNIT_TEST(OptimisticQueue_HP_seqcst);
diff --git a/tests/test-hdr/queue/hdr_queue_register.cpp b/tests/test-hdr/queue/hdr_queue_register.cpp
index 9f3e24bf..5f5e2beb 100644
--- a/tests/test-hdr/queue/hdr_queue_register.cpp
+++ b/tests/test-hdr/queue/hdr_queue_register.cpp
@@ -6,8 +6,8 @@
 #include "hdr_queue.h"          //TODO must be removed after refactoring
 #include "hdr_segmented_queue.h"
 
-CPPUNIT_TEST_SUITE_REGISTRATION( queue::HdrTestQueue );
-CPPUNIT_TEST_SUITE_REGISTRATION( queue::Queue_TestHeader); //TODO must be removed after refactoring
-CPPUNIT_TEST_SUITE_REGISTRATION( queue::HdrSegmentedQueue );
-CPPUNIT_TEST_SUITE_REGISTRATION( queue::IntrusiveQueueHeaderTest );
-CPPUNIT_TEST_SUITE_REGISTRATION( queue::HdrIntrusiveSegmentedQueue );
+CPPUNIT_TEST_SUITE_REGISTRATION_( queue::HdrTestQueue,               s_HdrTestQueue );
+CPPUNIT_TEST_SUITE_REGISTRATION_( queue::Queue_TestHeader,           s_Queue_TestHeader ); //TODO must be removed after refactoring
+CPPUNIT_TEST_SUITE_REGISTRATION_( queue::HdrSegmentedQueue,          s_HdrSegmentedQueue );
+CPPUNIT_TEST_SUITE_REGISTRATION_( queue::IntrusiveQueueHeaderTest,   s_IntrusiveQueueHeaderTest );
+CPPUNIT_TEST_SUITE_REGISTRATION_( queue::HdrIntrusiveSegmentedQueue, s_HdrIntrusiveSegmentedQueue );
diff --git a/tests/unit/queue/intrusive_queue_type.h b/tests/unit/queue/intrusive_queue_type.h
index 0336a56e..c5527b88 100644
--- a/tests/unit/queue/intrusive_queue_type.h
+++ b/tests/unit/queue/intrusive_queue_type.h
@@ -428,6 +428,24 @@ namespace queue {
 namespace std {
 
     // cds::intrusive::queue_stat
+    template <typename Counter>
+    static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::queue_stat<Counter> const& s)
+    {
+        return o
+            << "\tStatistics:\n"
+            << "\t\t     Enqueue count: " << s.m_EnqueueCount.get() << "\n"
+            << "\t\t      Enqueue race: " << s.m_EnqueueRace.get() << "\n"
+            << "\t\t     Dequeue count: " << s.m_DequeueCount.get() << "\n"
+            << "\t\t      Dequeue race: " << s.m_DequeueRace.get() << "\n"
+            << "\t\tAdvance tail error: " << s.m_AdvanceTailError.get() << "\n"
+            << "\t\t          Bad tail: " << s.m_BadTail.get() << "\n";
+    }
+    static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::queue_dummy_stat const& s)
+    {
+        return o;
+    }
+
+
     template <typename Counter>
     static inline std::ostream& operator <<( std::ostream& o, cds::intrusive::msqueue::stat<Counter> const& s )
     {
diff --git a/tests/unit/queue/queue_type.h b/tests/unit/queue/queue_type.h
index 5b4caa9d..13b561c4 100644
--- a/tests/unit/queue/queue_type.h
+++ b/tests/unit/queue/queue_type.h
@@ -108,7 +108,7 @@ namespace queue {
 
         struct traits_MSQueue_michaelAlloc : public cds::container::msqueue::traits
         {
-            typedef cds::memory::MichaelAllocator<int>  allocator;
+            typedef memory::MichaelAllocator<int>  allocator;
         };
         typedef cds::container::MSQueue<cds::gc::HP,  Value, traits_MSQueue_michaelAlloc > MSQueue_HP_michaelAlloc;
         typedef cds::container::MSQueue<cds::gc::DHP, Value, traits_MSQueue_michaelAlloc > MSQueue_DHP_michaelAlloc;
@@ -561,6 +561,24 @@ namespace queue {
 namespace std {
 
     // cds::intrusive::queue_stat
+    template <typename Counter>
+    static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::queue_stat<Counter> const& s)
+    {
+        return o
+            << "\tStatistics:\n"
+            << "\t\t     Enqueue count: " << s.m_EnqueueCount.get() << "\n"
+            << "\t\t      Enqueue race: " << s.m_EnqueueRace.get() << "\n"
+            << "\t\t     Dequeue count: " << s.m_DequeueCount.get() << "\n"
+            << "\t\t      Dequeue race: " << s.m_DequeueRace.get() << "\n"
+            << "\t\tAdvance tail error: " << s.m_AdvanceTailError.get() << "\n"
+            << "\t\t          Bad tail: " << s.m_BadTail.get() << "\n";
+    }
+    static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::queue_dummy_stat const& s)
+    {
+        return o;
+    }
+
+
     template <typename Counter>
     static inline std::ostream& operator <<( std::ostream& o, cds::container::msqueue::stat<Counter> const& s )
     {
-- 
2.34.1