Fixed bug in RCU batch_retire()
[libcds.git] / cds / urcu / details / gpi.h
index 783a3064d3a8394fdfcba36b5723ef76119aabf4..23c105e18b938f3b37bdf3b8542676a6a2924898 100644 (file)
@@ -111,11 +111,8 @@ namespace cds { namespace urcu {
         virtual void retire_ptr( retired_ptr& p )
         {
             synchronize();
-            if ( p.m_p ) {
-                CDS_TSAN_ANNOTATE_IGNORE_RW_BEGIN;
+            if ( p.m_p )
                 p.free();
-                CDS_TSAN_ANNOTATE_IGNORE_RW_END;
-            }
         }
 
         /// Retires the pointer chain [\p itFirst, \p itLast)
@@ -133,16 +130,27 @@ namespace cds { namespace urcu {
             }
         }
 
+        /// Retires the pointer chain until \p Func returns \p nullptr retired pointer
+        template <typename Func>
+        void batch_retire( Func e )
+        {
+            retired_ptr p{ e() };
+            if ( p.m_p ) {
+                synchronize();
+                while ( p.m_p ) {
+                    retired_ptr pr( p );
+                    p = e();
+                    pr.free();
+                }
+            }
+        }
+
         /// Waits to finish a grace period
         void synchronize()
         {
-            atomics::atomic_thread_fence( atomics::memory_order_acquire );
-            {
-                std::unique_lock<lock_type> sl( m_Lock );
-                flip_and_wait();
-                flip_and_wait();
-            }
-            atomics::atomic_thread_fence( atomics::memory_order_release );
+            std::unique_lock<lock_type> sl( m_Lock );
+            flip_and_wait();
+            flip_and_wait();
         }
 
         //@cond