Uses different pass count for different parallel queue test cases
[libcds.git] / cds / opt / buffer.h
index 76dc4cf1066422726d56dc434435d3558d32bfd2..2623069eca3d967a69a33e0fcbd82422e8d22f4e 100644 (file)
@@ -1,11 +1,11 @@
 /*
     This file is a part of libcds - Concurrent Data Structures library
 
-    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
+    (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:
 
@@ -25,7 +25,7 @@
     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.     
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 #ifndef CDSLIB_OPT_BUFFER_H
@@ -139,14 +139,14 @@ namespace cds { namespace opt {
             /// Get item \p i
             value_type& operator []( size_t i )
             {
-                assert( i < capacity() );
+                assert( i < capacity());
                 return m_buffer[i].v;
             }
 
             /// Get item \p i, const version
             const value_type& operator []( size_t i ) const
             {
-                assert( i < capacity() );
+                assert( i < capacity());
                 return m_buffer[i].v;
             }
 
@@ -159,7 +159,7 @@ namespace cds { namespace opt {
             /// Zeroize the buffer
             void zeroize()
             {
-                memset( m_buffer, 0, capacity() * sizeof(m_buffer[0]) );
+                memset( m_buffer, 0, capacity() * sizeof(m_buffer[0]));
             }
 
             /// Returns pointer to buffer array
@@ -173,6 +173,30 @@ namespace cds { namespace opt {
             {
                 return &( m_buffer[0].v );
             }
+
+            /// Returns <tt> idx % capacity() </tt>
+            /**
+                If the buffer size is a power of two, binary arithmethics is used
+                instead of modulo arithmetics
+            */
+            size_t mod( size_t idx )
+            {
+                static_if( c_bExp2 )
+                    return idx & ( capacity() - 1 );
+                else
+                    return idx % capacity();
+            }
+
+            //@cond
+            template <typename I>
+            typename std::enable_if< sizeof(I) != sizeof(size_t), size_t >::type mod( I idx )
+            {
+                static_if( c_bExp2 )
+                    return static_cast<size_t>( idx & static_cast<I>( capacity() - 1 ));
+                else
+                    return static_cast<size_t>( idx % capacity());
+            }
+            //@endcond
         };
 
         /// Static initialized buffer
@@ -231,14 +255,14 @@ namespace cds { namespace opt {
             /// Get item \p i
             value_type& operator []( size_t i )
             {
-                assert( i < capacity() );
+                assert( i < capacity());
                 return m_buffer[i];
             }
 
             /// Get item \p i, const version
             const value_type& operator []( size_t i ) const
             {
-                assert( i < capacity() );
+                assert( i < capacity());
                 return m_buffer[i];
             }
 
@@ -251,7 +275,7 @@ namespace cds { namespace opt {
             /// Zeroize the buffer
             void zeroize()
             {
-                memset( m_buffer, 0, capacity() * sizeof(m_buffer[0]) );
+                memset( m_buffer, 0, capacity() * sizeof(m_buffer[0]));
             }
 
             /// Returns pointer to buffer array
@@ -265,6 +289,30 @@ namespace cds { namespace opt {
             {
                 return m_buffer;
             }
+
+            /// Returns <tt> idx % capacity() </tt>
+            /**
+            If the buffer size is a power of two, binary arithmethics is used
+            instead of modulo arithmetics
+            */
+            size_t mod( size_t idx )
+            {
+                static_if( c_bExp2 )
+                    return idx & ( capacity() - 1 );
+                else
+                    return idx % capacity();
+            }
+
+            //@cond
+            template <typename I>
+            typename std::enable_if< sizeof( I ) != sizeof( size_t ), size_t >::type mod( I idx )
+            {
+                static_if( c_bExp2 )
+                    return static_cast<size_t>( idx & static_cast<I>( capacity() - 1 ));
+                else
+                    return static_cast<size_t>( idx % capacity());
+            }
+            //@endcond
         };
 
         /// Dynamically allocated uninitialized buffer
@@ -286,17 +334,18 @@ namespace cds { namespace opt {
         class uninitialized_dynamic_buffer
         {
         public:
-            typedef T   value_type;   ///< Value type
+            typedef T     value_type;   ///< Value type
+            typedef Alloc allocator;    ///< Allocator type;
             static CDS_CONSTEXPR const bool c_bExp2 = Exp2; ///< \p Exp2 flag
 
             /// Rebind buffer for other template parameters
-            template <typename Q, typename Alloc2=Alloc, bool Exp22 = c_bExp2>
+            template <typename Q, typename Alloc2= allocator, bool Exp22 = c_bExp2>
             struct rebind {
                 typedef uninitialized_dynamic_buffer<Q, Alloc2, Exp22> other;  ///< Rebinding result type
             };
 
             //@cond
-            typedef typename Alloc::template rebind<value_type>::other allocator_type;
+            typedef typename allocator::template rebind<value_type>::other allocator_type;
             //@endcond
 
         private:
@@ -332,14 +381,14 @@ namespace cds { namespace opt {
             /// Get item \p i
             value_type& operator []( size_t i )
             {
-                assert( i < capacity() );
+                assert( i < capacity());
                 return m_buffer[i];
             }
 
             /// Get item \p i, const version
             const value_type& operator []( size_t i ) const
             {
-                assert( i < capacity() );
+                assert( i < capacity());
                 return m_buffer[i];
             }
 
@@ -352,7 +401,7 @@ namespace cds { namespace opt {
             /// Zeroize the buffer
             void zeroize()
             {
-                memset( m_buffer, 0, capacity() * sizeof(m_buffer[0]) );
+                memset( m_buffer, 0, capacity() * sizeof(m_buffer[0]));
             }
 
             /// Returns pointer to buffer array
@@ -366,6 +415,30 @@ namespace cds { namespace opt {
             {
                 return m_buffer;
             }
+
+            /// Returns <tt> idx % capacity() </tt>
+            /**
+                If the buffer size is a power of two, binary arithmethics is used
+                instead of modulo arithmetics
+            */
+            size_t mod( size_t idx )
+            {
+                static_if ( c_bExp2 )
+                    return idx & ( capacity() - 1 );
+                else
+                    return idx % capacity();
+            }
+
+            //@cond
+            template <typename I>
+            typename std::enable_if< sizeof( I ) != sizeof( size_t ), size_t >::type mod( I idx )
+            {
+                static_if ( c_bExp2 )
+                    return static_cast<size_t>( idx & static_cast<I>( capacity() - 1 ));
+                else
+                    return static_cast<size_t>( idx % capacity());
+            }
+            //@endcond
         };
 
 
@@ -387,17 +460,18 @@ namespace cds { namespace opt {
         class initialized_dynamic_buffer
         {
         public:
-            typedef T   value_type;   ///< Value type
+            typedef T     value_type;   ///< Value type
+            typedef Alloc allocator;    ///< Allocator type
             static CDS_CONSTEXPR const bool c_bExp2 = Exp2; ///< \p Exp2 flag
 
             /// Rebind buffer for other template parameters
-            template <typename Q, typename Alloc2=Alloc, bool Exp22 = c_bExp2>
+            template <typename Q, typename Alloc2= allocator, bool Exp22 = c_bExp2>
             struct rebind {
                 typedef initialized_dynamic_buffer<Q, Alloc2, Exp22> other;  ///< Rebinding result type
             };
 
             //@cond
-            typedef cds::details::Allocator<value_type, Alloc>   allocator_type;
+            typedef cds::details::Allocator<value_type, allocator>   allocator_type;
             //@endcond
 
         private:
@@ -435,14 +509,14 @@ namespace cds { namespace opt {
             /// Get item \p i
             value_type& operator []( size_t i )
             {
-                assert( i < capacity() );
+                assert( i < capacity());
                 return m_buffer[i];
             }
 
             /// Get item \p i, const version
             const value_type& operator []( size_t i ) const
             {
-                assert( i < capacity() );
+                assert( i < capacity());
                 return m_buffer[i];
             }
 
@@ -455,7 +529,7 @@ namespace cds { namespace opt {
             /// Zeroize the buffer
             void zeroize()
             {
-                memset( m_buffer, 0, capacity() * sizeof(m_buffer[0]) );
+                memset( m_buffer, 0, capacity() * sizeof(m_buffer[0]));
             }
 
             /// Returns pointer to buffer array
@@ -469,6 +543,30 @@ namespace cds { namespace opt {
             {
                 return m_buffer;
             }
+
+            /// Returns <tt> idx % capacity() </tt>
+            /**
+            If the buffer size is a power of two, binary arithmethics is used
+            instead of modulo arithmetics
+            */
+            size_t mod( size_t idx )
+            {
+                static_if( c_bExp2 )
+                    return idx & ( capacity() - 1 );
+                else
+                    return idx % capacity();
+            }
+
+            //@cond
+            template <typename I>
+            typename std::enable_if< sizeof( I ) != sizeof( size_t ), size_t >::type mod( I idx )
+            {
+                static_if( c_bExp2 )
+                    return static_cast<size_t>( idx & static_cast<I>( capacity() - 1 ));
+                else
+                    return static_cast<size_t>( idx % capacity());
+            }
+            //@endcond
         };
 
     }   // namespace v