bugfix in cds::gc::HP::guarded_ptr
authorkhizmax <libcds.dev@gmail.com>
Fri, 21 Nov 2014 07:13:01 +0000 (10:13 +0300)
committerkhizmax <libcds.dev@gmail.com>
Fri, 21 Nov 2014 07:13:01 +0000 (10:13 +0300)
cds/gc/impl/dhp_decl.h
cds/gc/impl/hp_decl.h
tests/test-hdr/ordered_list/hdr_intrusive_michael.h

index 333c6d7..6da2073 100644 (file)
@@ -513,7 +513,7 @@ namespace cds { namespace gc {
             /// Checks if the guarded pointer is \p nullptr
             bool empty() const CDS_NOEXCEPT
             {
             /// 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 <tt>!empty()</tt>
             }
 
             /// \p bool operator returns <tt>!empty()</tt>
index 56c1db6..bffc526 100644 (file)
@@ -477,9 +477,16 @@ namespace cds { namespace gc {
             /// Move-assignment operator
             guarded_ptr& operator=( guarded_ptr&& gp ) CDS_NOEXCEPT
             {
             /// 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;
             }
 
                 return *this;
             }
 
@@ -510,7 +517,7 @@ namespace cds { namespace gc {
             /// Checks if the guarded pointer is \p nullptr
             bool empty() const CDS_NOEXCEPT
             {
             /// 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 <tt>!empty()</tt>
             }
 
             /// \p bool operator returns <tt>!empty()</tt>
index 63ff419..864dcc1 100644 (file)
@@ -474,22 +474,22 @@ namespace ordlist {
 
                 for ( int i=0; i < nLimit; ++i ) {
                     gp = l.get( arrItem[i].nKey );
 
                 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.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 );
 
                     gp = l.extract( arrItem[i].nKey );
-                    CPPUNIT_ASSERT( gp );
+                    CPPUNIT_ASSERT_EX( gp, "i=" << i );
                     CPPUNIT_ASSERT( !gp.empty());
                     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 );
 
                     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 ));
                 }
                 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() );
                 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.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() );
 
                     gp = l.extract_with( itm, other_less() );
-                    CPPUNIT_ASSERT( gp );
+                    CPPUNIT_ASSERT_EX( gp, "i=" << i );
                     CPPUNIT_ASSERT( !gp.empty());
                     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() );
 
                     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() ));
                 }
                 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 ) {
                     {
 
                 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 );
 
                         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] );
                     {
                 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 );
 
                         ep = l.extract_with( itm, other_less() );
                         CPPUNIT_ASSERT( ep );