From c0720d814a5cbb40dcd8f3c278dbc30a833e429b Mon Sep 17 00:00:00 2001 From: khizmax Date: Sun, 12 Jul 2015 10:57:06 +0300 Subject: [PATCH] Fixed bug in RCU batch_retire() --- cds/urcu/details/gpb.h | 10 +++++++--- cds/urcu/details/gpi.h | 7 +++++-- cds/urcu/details/gpt.h | 10 +++++++--- cds/urcu/details/sig_buffered.h | 10 +++++++--- cds/urcu/details/sig_threaded.h | 10 +++++++--- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/cds/urcu/details/gpb.h b/cds/urcu/details/gpb.h index 9441f26b..94e27b65 100644 --- a/cds/urcu/details/gpb.h +++ b/cds/urcu/details/gpb.h @@ -174,8 +174,9 @@ namespace cds { namespace urcu { { uint64_t nEpoch = m_nCurEpoch.load( atomics::memory_order_relaxed ); while ( itFirst != itLast ) { - push_buffer( epoch_retired_ptr( *itFirst, nEpoch )); + epoch_retired_ptr ep( *itFirst, nEpoch ); ++itFirst; + push_buffer( std::move(ep) ); } } @@ -184,8 +185,11 @@ namespace cds { namespace urcu { void batch_retire( Func e ) { uint64_t nEpoch = m_nCurEpoch.load( atomics::memory_order_relaxed ); - for ( retired_ptr p{ e() }; p.m_p; p = e() ) - push_buffer( epoch_retired_ptr( p, nEpoch )); + for ( retired_ptr p{ e() }; p.m_p; ) { + epoch_retired_ptr ep( p, nEpoch ); + p = e(); + push_buffer( std::move(ep)); + } } /// Wait to finish a grace period and then clear the buffer diff --git a/cds/urcu/details/gpi.h b/cds/urcu/details/gpi.h index ce9bb53a..23c105e1 100644 --- a/cds/urcu/details/gpi.h +++ b/cds/urcu/details/gpi.h @@ -137,8 +137,11 @@ namespace cds { namespace urcu { retired_ptr p{ e() }; if ( p.m_p ) { synchronize(); - for ( ; p.m_p; p = e() ) - p.free(); + while ( p.m_p ) { + retired_ptr pr( p ); + p = e(); + pr.free(); + } } } diff --git a/cds/urcu/details/gpt.h b/cds/urcu/details/gpt.h index 1f594148..4699ef2f 100644 --- a/cds/urcu/details/gpt.h +++ b/cds/urcu/details/gpt.h @@ -178,8 +178,9 @@ namespace cds { namespace urcu { { uint64_t nEpoch = m_nCurEpoch.load( atomics::memory_order_relaxed ); while ( itFirst != itLast ) { - push_buffer( epoch_retired_ptr( *itFirst, nEpoch )); + epoch_retired_ptr ep( *itFirst, nEpoch ); ++itFirst; + push_buffer( std::move(ep)); } } @@ -188,8 +189,11 @@ namespace cds { namespace urcu { void batch_retire( Func e ) { uint64_t nEpoch = m_nCurEpoch.load( atomics::memory_order_relaxed ); - for ( retired_ptr p{ e() }; p.m_p; p = e() ) - push_buffer( epoch_retired_ptr( p, nEpoch )); + for ( retired_ptr p{ e() }; p.m_p; ) { + epoch_retired_ptr ep( p, nEpoch ); + p = e(); + push_buffer( std::move(ep)); + } } diff --git a/cds/urcu/details/sig_buffered.h b/cds/urcu/details/sig_buffered.h index 05b98623..d1c4569c 100644 --- a/cds/urcu/details/sig_buffered.h +++ b/cds/urcu/details/sig_buffered.h @@ -172,8 +172,9 @@ namespace cds { namespace urcu { { uint64_t nEpoch = m_nCurEpoch.load( atomics::memory_order_relaxed ); while ( itFirst != itLast ) { - push_buffer( epoch_retired_ptr( *itFirst, nEpoch )); + epoch_retired_ptr ep( *itFirst, nEpoch ); ++itFirst; + push_buffer( std::move(ep)); } } @@ -182,8 +183,11 @@ namespace cds { namespace urcu { void batch_retire( Func e ) { uint64_t nEpoch = m_nCurEpoch.load( atomics::memory_order_relaxed ); - for ( retired_ptr p{ e() }; p.m_p; p = e() ) - push_buffer( epoch_retired_ptr( p, nEpoch )); + for ( retired_ptr p{ e() }; p.m_p; ) { + epoch_retired_ptr ep( p, nEpoch ); + p = e(); + push_buffer( std::move(ep)); + } } /// Wait to finish a grace period and then clear the buffer diff --git a/cds/urcu/details/sig_threaded.h b/cds/urcu/details/sig_threaded.h index 93e1aa24..f4031862 100644 --- a/cds/urcu/details/sig_threaded.h +++ b/cds/urcu/details/sig_threaded.h @@ -177,8 +177,9 @@ namespace cds { namespace urcu { { uint64_t nEpoch = m_nCurEpoch.load( atomics::memory_order_relaxed ); while ( itFirst != itLast ) { - push_buffer( epoch_retired_ptr( *itFirst, nEpoch ) ); + epoch_retired_ptr ep( *itFirst, nEpoch ); ++itFirst; + push_buffer( std::move(ep)); } } @@ -187,8 +188,11 @@ namespace cds { namespace urcu { void batch_retire( Func e ) { uint64_t nEpoch = m_nCurEpoch.load( atomics::memory_order_relaxed ); - for ( retired_ptr p{ e() }; p.m_p; p = e() ) - push_buffer( epoch_retired_ptr( p, nEpoch )); + for ( retired_ptr p{ e() }; p.m_p; ) { + epoch_retired_ptr ep( p, nEpoch ); + p = e(); + push_buffer( std::move(ep)); + } } -- 2.34.1