Fixed Clang build
[libcds.git] / cds / intrusive / msqueue.h
index e9b30f7546668f91c78327bb1dfc564de85b5dc4..5eafbba3b0f9bb93ff7620d91128cb75c2f3a5cd 100644 (file)
@@ -1,4 +1,32 @@
-//$$CDS-header$$
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
+
+    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_MSQUEUE_H
 #define CDSLIB_INTRUSIVE_MSQUEUE_H
@@ -171,8 +199,8 @@ namespace cds { namespace intrusive {
             /// Link checking, see \p cds::opt::link_checker
             static CDS_CONSTEXPR const opt::link_check_type link_checker = opt::debug_check_link;
 
-            /// Alignment for internal queue data. Default is \p opt::cache_line_alignment
-            enum { alignment = opt::cache_line_alignment };
+            /// 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
@@ -190,7 +218,7 @@ namespace cds { namespace intrusive {
             - \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 (internal statistics disabled).
-            - \p opt::alignment - the alignment for internal queue data. Default is \p opt::cache_line_alignment
+            - \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).
 
@@ -287,7 +315,7 @@ namespace cds { namespace intrusive {
         // Example 2:
         //  MSQueue with Hazard Pointer garbage collector,
         //  member hook + item disposer + item counter,
-        //  without alignment of internal queue data
+        //  without padding of internal queue data
         //  Use msqueue::make_traits
         struct Bar
         {
@@ -307,7 +335,7 @@ namespace cds { namespace intrusive {
                 >
                 ,ci::opt::disposer< fooDisposer >
                 ,cds::opt::item_counter< cds::atomicity::item_counter >
-                ,cds::opt::alignment< cds::opt::no_special_alignment >
+                ,cds::opt::padding< cds::opt::no_special_padding >
             >::type
         > barQueue;
         \endcode
@@ -337,7 +365,7 @@ namespace cds { namespace intrusive {
             typedef MSQueue< GC2, T2, Traits2 > other;   ///< Rebinding result
         };
 
-        static CDS_CONSTEXPR const size_t m_nHazardPtrCount = 2; ///< Count of hazard pointer required for the algorithm
+        static CDS_CONSTEXPR const size_t c_nHazardPtrCount = 2; ///< Count of hazard pointer required for the algorithm
 
     protected:
         //@cond
@@ -345,14 +373,16 @@ namespace cds { namespace intrusive {
         // GC and node_type::gc must be the same
         static_assert((std::is_same<gc, typename node_type::gc>::value), "GC and node_type::gc must be the same");
 
-        typedef typename opt::details::alignment_setter< typename node_type::atomic_node_ptr, traits::alignment >::type aligned_node_ptr;
-        typedef typename opt::details::alignment_setter< node_type, traits::alignment >::type dummy_node_type;
+        typedef typename node_type::atomic_node_ptr atomic_node_ptr;
 
-        aligned_node_ptr    m_pHead ;           ///< Queue's head pointer
-        aligned_node_ptr    m_pTail ;           ///< Queue's tail pointer
-        dummy_node_type     m_Dummy ;           ///< dummy node
-        item_counter        m_ItemCounter   ;   ///< Item counter
-        stat                m_Stat  ;           ///< Internal statistics
+        atomic_node_ptr    m_pHead;        ///< Queue's head pointer
+        typename opt::details::apply_padding< atomic_node_ptr, traits::padding >::padding_type pad1_;
+        atomic_node_ptr    m_pTail;        ///< Queue's tail pointer
+        typename opt::details::apply_padding< atomic_node_ptr, traits::padding >::padding_type pad2_;
+        node_type          m_Dummy;        ///< dummy node
+        typename opt::details::apply_padding< node_type, traits::padding >::padding_type pad3_;
+        item_counter        m_ItemCounter; ///< Item counter
+        stat                m_Stat;        ///< Internal statistics
         //@endcond
 
         //@cond
@@ -554,8 +584,8 @@ namespace cds { namespace intrusive {
         bool empty() const
         {
             typename gc::Guard guard;
-            return guard.protect( m_pHead, []( node_type * p ) -> value_type * { return node_traits::to_value_ptr( p );})
-                ->m_pNext.load( memory_model::memory_order_relaxed ) == nullptr;
+            node_type * p = guard.protect( m_pHead, []( node_type * p ) -> value_type * { return node_traits::to_value_ptr( p );});
+            return p->m_pNext.load( memory_model::memory_order_relaxed ) == nullptr;
         }
 
         /// Clear the queue