From: khizmax Date: Fri, 21 Nov 2014 07:13:01 +0000 (+0300) Subject: bugfix in cds::gc::HP::guarded_ptr X-Git-Tag: v2.0.0~62 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=libcds.git;a=commitdiff_plain;h=e9fda6acf3c6a28fb822cfe85d784682eb8dbbe0 bugfix in cds::gc::HP::guarded_ptr --- diff --git a/cds/gc/impl/dhp_decl.h b/cds/gc/impl/dhp_decl.h index 333c6d79..6da2073a 100644 --- a/cds/gc/impl/dhp_decl.h +++ b/cds/gc/impl/dhp_decl.h @@ -513,7 +513,7 @@ namespace cds { namespace gc { /// Checks if the guarded pointer is \p nullptr bool empty() const CDS_NOEXCEPT { - return !m_guard.is_initialized() || m_guard.get() == nullptr; + return !m_guard.is_initialized() || m_guard.get( atomics::memory_order_relaxed ) == nullptr; } /// \p bool operator returns !empty() diff --git a/cds/gc/impl/hp_decl.h b/cds/gc/impl/hp_decl.h index 56c1db6f..bffc5268 100644 --- a/cds/gc/impl/hp_decl.h +++ b/cds/gc/impl/hp_decl.h @@ -477,9 +477,16 @@ namespace cds { namespace gc { /// Move-assignment operator guarded_ptr& operator=( guarded_ptr&& gp ) CDS_NOEXCEPT { - free_guard(); - m_pGuard = gp.m_pGuard; - gp.m_pGuard = nullptr; + // Hazard Pointer array is organized as a stack + if ( m_pGuard && m_pGuard > gp.m_pGuard ) { + m_pGuard->set( gp.m_pGuard->get(atomics::memory_order_relaxed) ); + gp.free_guard(); + } + else { + free_guard(); + m_pGuard = gp.m_pGuard; + gp.m_pGuard = nullptr; + } return *this; } @@ -510,7 +517,7 @@ namespace cds { namespace gc { /// Checks if the guarded pointer is \p nullptr bool empty() const CDS_NOEXCEPT { - return !m_pGuard || m_pGuard->get() == nullptr; + return !m_pGuard || m_pGuard->get( atomics::memory_order_relaxed ) == nullptr; } /// \p bool operator returns !empty() diff --git a/tests/test-hdr/ordered_list/hdr_intrusive_michael.h b/tests/test-hdr/ordered_list/hdr_intrusive_michael.h index 63ff419a..864dcc1e 100644 --- a/tests/test-hdr/ordered_list/hdr_intrusive_michael.h +++ b/tests/test-hdr/ordered_list/hdr_intrusive_michael.h @@ -474,22 +474,22 @@ namespace ordlist { for ( int i=0; i < nLimit; ++i ) { gp = l.get( arrItem[i].nKey ); - CPPUNIT_ASSERT( gp ); + CPPUNIT_ASSERT_EX( gp, "i=" << i ); CPPUNIT_ASSERT( !gp.empty()); - CPPUNIT_ASSERT( gp->nKey == arrItem[i].nKey ); - CPPUNIT_ASSERT( gp->nVal == arrItem[i].nVal ); + CPPUNIT_CHECK( gp->nKey == arrItem[i].nKey ); + CPPUNIT_CHECK( gp->nVal == arrItem[i].nVal ); gp = l.extract( arrItem[i].nKey ); - CPPUNIT_ASSERT( gp ); + CPPUNIT_ASSERT_EX( gp, "i=" << i ); CPPUNIT_ASSERT( !gp.empty()); - CPPUNIT_ASSERT( gp->nKey == arrItem[i].nKey ); - CPPUNIT_ASSERT( gp->nVal == arrItem[i].nVal ); + CPPUNIT_CHECK( gp->nKey == arrItem[i].nKey ); + CPPUNIT_CHECK( gp->nVal == arrItem[i].nVal ); gp = l.get( arrItem[i].nKey ); - CPPUNIT_ASSERT( !gp ); - CPPUNIT_ASSERT( gp.empty()); - CPPUNIT_ASSERT( !l.extract( arrItem[i].nKey )); - CPPUNIT_ASSERT( gp.empty()); + CPPUNIT_CHECK( !gp ); + CPPUNIT_CHECK( gp.empty()); + CPPUNIT_CHECK( !l.extract( arrItem[i].nKey )); + CPPUNIT_CHECK( gp.empty()); } CPPUNIT_ASSERT( l.empty() ); CPPUNIT_ASSERT( !l.get( nLimit/2 )); @@ -507,22 +507,22 @@ namespace ordlist { for ( int i=0; i < nLimit; ++i ) { other_item itm( arrItem[i].nKey ); gp = l.get_with( itm, other_less() ); - CPPUNIT_ASSERT( gp ); + CPPUNIT_ASSERT_EX( gp, "i=" << i ); CPPUNIT_ASSERT( !gp.empty()); - CPPUNIT_ASSERT( gp->nKey == arrItem[i].nKey ); - CPPUNIT_ASSERT( gp->nVal == arrItem[i].nVal ); + CPPUNIT_CHECK( gp->nKey == arrItem[i].nKey ); + CPPUNIT_CHECK( gp->nVal == arrItem[i].nVal ); gp = l.extract_with( itm, other_less() ); - CPPUNIT_ASSERT( gp ); + CPPUNIT_ASSERT_EX( gp, "i=" << i ); CPPUNIT_ASSERT( !gp.empty()); - CPPUNIT_ASSERT( gp->nKey == arrItem[i].nKey ); - CPPUNIT_ASSERT( gp->nVal == arrItem[i].nVal ); + CPPUNIT_CHECK( gp->nKey == arrItem[i].nKey ); + CPPUNIT_CHECK( gp->nVal == arrItem[i].nVal ); gp = l.get_with( itm, other_less() ); - CPPUNIT_ASSERT( !gp ); - CPPUNIT_ASSERT( gp.empty()); - CPPUNIT_ASSERT( !l.extract_with( itm, other_less() )); - CPPUNIT_ASSERT( gp.empty()); + CPPUNIT_CHECK( !gp ); + CPPUNIT_CHECK( gp.empty()); + CPPUNIT_CHECK( !l.extract_with( itm, other_less() )); + CPPUNIT_CHECK( gp.empty()); } CPPUNIT_ASSERT( l.empty() ); CPPUNIT_ASSERT( !l.get_with( other_item(nLimit/2), other_less() )); @@ -571,11 +571,13 @@ namespace ordlist { for ( int i = 0; i < nLimit; ++i ) { { - rcu_lock lock; - value_type * pGet = l.get( a[i] ); - CPPUNIT_ASSERT( pGet != nullptr ); - CPPUNIT_CHECK( pGet->nKey == a[i] ); - CPPUNIT_CHECK( pGet->nVal == a[i] * 2 ); + { + rcu_lock lock; + value_type * pGet = l.get( a[i] ); + CPPUNIT_ASSERT( pGet != nullptr ); + CPPUNIT_CHECK( pGet->nKey == a[i] ); + CPPUNIT_CHECK( pGet->nVal == a[i] * 2 ); + } ep = l.extract( a[i] ); CPPUNIT_ASSERT( ep ); @@ -611,11 +613,13 @@ namespace ordlist { for ( int i = 0; i < nLimit; ++i ) { other_item itm( a[i] ); { - rcu_lock lock; - value_type * pGet = l.get_with( itm, other_less() ); - CPPUNIT_ASSERT( pGet != nullptr ); - CPPUNIT_CHECK( pGet->nKey == a[i] ); - CPPUNIT_CHECK( pGet->nVal == a[i] * 2 ); + { + rcu_lock lock; + value_type * pGet = l.get_with( itm, other_less() ); + CPPUNIT_ASSERT( pGet != nullptr ); + CPPUNIT_CHECK( pGet->nKey == a[i] ); + CPPUNIT_CHECK( pGet->nVal == a[i] * 2 ); + } ep = l.extract_with( itm, other_less() ); CPPUNIT_ASSERT( ep );