Fixed max bucket count error in SplitList
[libcds.git] / cds / intrusive / split_list_rcu.h
index 8deeb7ce75b84505d8a7b77f3988011f8f6c46a2..293489ffb1d161dd838c5dc4c69410068ad8881b 100644 (file)
@@ -3,9 +3,10 @@
 #ifndef CDSLIB_INTRUSIVE_SPLIT_LIST_RCU_H
 #define CDSLIB_INTRUSIVE_SPLIT_LIST_RCU_H
 
+#include <limits>
+
 #include <cds/intrusive/details/split_list_base.h>
 #include <cds/details/binary_functor_wrapper.h>
-#include <limits>
 
 namespace cds { namespace intrusive {
 
@@ -363,17 +364,20 @@ namespace cds { namespace intrusive {
             if ( ++m_ItemCounter <= nMaxCount )
                 return;
 
-            const size_t nLoadFactor = m_Buckets.load_factor();
             size_t sz = m_nBucketCountLog2.load(memory_model::memory_order_relaxed);
             const size_t nBucketCount = static_cast<size_t>(1) << sz;
-            if ( nMaxCount < max_item_count( nBucketCount, nLoadFactor ))
-                return; // someone already have updated m_nBucketCountLog2, so stop here
-
-            const size_t nNewMaxCount = (nBucketCount < m_Buckets.capacity()) ? max_item_count( nBucketCount << 1, nLoadFactor )
-                                                                              : std::numeric_limits<size_t>::max();
-            m_nMaxItemCount.compare_exchange_strong( nMaxCount, nNewMaxCount, memory_model::memory_order_relaxed,
-                memory_model::memory_order_relaxed );
-            m_nBucketCountLog2.compare_exchange_strong( sz, sz + 1, memory_model::memory_order_relaxed, memory_model::memory_order_relaxed );
+            if ( nBucketCount < m_Buckets.capacity() ) {
+                // we may grow the bucket table
+                const size_t nLoadFactor = m_Buckets.load_factor();
+                if ( nMaxCount < max_item_count( nBucketCount, nLoadFactor ))
+                    return; // someone already have updated m_nBucketCountLog2, so stop here
+
+                const size_t nNewMaxCount = (nBucketCount < m_Buckets.capacity()) ? max_item_count( nBucketCount << 1, nLoadFactor )
+                                                                                  : std::numeric_limits<size_t>::max();
+                m_nMaxItemCount.compare_exchange_strong( nMaxCount, nNewMaxCount, memory_model::memory_order_relaxed,
+                    atomics::memory_order_relaxed );
+                m_nBucketCountLog2.compare_exchange_strong( sz, sz + 1, memory_model::memory_order_relaxed, atomics::memory_order_relaxed );
+            }
         }
 
         template <typename Q, typename Compare, typename Func>