From: khizmax Date: Fri, 3 Apr 2015 15:52:01 +0000 (+0300) Subject: Fixed BronsonAVLTree insert/update bug (incomplete) X-Git-Tag: v2.1.0~283 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=721e9a15642fe8fb6ea056f5d837f0de3543edec;p=libcds.git Fixed BronsonAVLTree insert/update bug (incomplete) --- diff --git a/cds/container/details/bronson_avltree_base.h b/cds/container/details/bronson_avltree_base.h index 349e36ed..ea2757d9 100644 --- a/cds/container/details/bronson_avltree_base.h +++ b/cds/container/details/bronson_avltree_base.h @@ -181,6 +181,7 @@ namespace cds { namespace container { event_counter m_nFindWaitShrinking; ///< Count of waiting until shrinking completed duting \p find() call event_counter m_nInsertSuccess; ///< Count of inserting data node + event_counter m_nInsertFailed; ///< Count of insert failures event_counter m_nRelaxedInsertFailed; ///< Count of false creating of data nodes (only if @ref bronson_avltree::relaxed_insert "relaxed insertion" is enabled) event_counter m_nInsertRetry; ///< Count of insert retries via concurrent operations event_counter m_nUpdateWaitShrinking; ///< Count of waiting until shrinking completed during \p update() call @@ -222,7 +223,8 @@ namespace cds { namespace container { void onFindRetry() { ++m_nFindRetry ; } void onFindWaitShrinking() { ++m_nFindWaitShrinking; } - void onInsertSuccess() { ++m_nInsertSuccess ; } + void onInsertSuccess() { ++m_nInsertSuccess; } + void onInsertFailed() { ++m_nInsertFailed; } void onRelaxedInsertFailed() { ++m_nRelaxedInsertFailed; } void onInsertRetry() { ++m_nInsertRetry ; } void onUpdateWaitShrinking() { ++m_nUpdateWaitShrinking; } @@ -269,6 +271,7 @@ namespace cds { namespace container { void onFindWaitShrinking() const {} void onInsertSuccess() const {} + void onInsertFailed() const {} void onRelaxedInsertFailed() const {} void onInsertRetry() const {} void onUpdateWaitShrinking() const {} diff --git a/cds/container/impl/bronson_avltree_map_rcu.h b/cds/container/impl/bronson_avltree_map_rcu.h index 13347c5b..36449e81 100644 --- a/cds/container/impl/bronson_avltree_map_rcu.h +++ b/cds/container/impl/bronson_avltree_map_rcu.h @@ -1086,11 +1086,8 @@ namespace cds { namespace container { assert( nVersion != node_type::unlinked ); int nCmp = cmp( key, pNode->m_key ); - if ( nCmp == 0 ) { - if ( nFlags & update_flags::allow_update ) - return try_update_node( funcUpdate, pNode, nVersion, disp ); - return update_flags::failed; - } + if ( nCmp == 0 ) + return try_update_node( nFlags, funcUpdate, pNode, nVersion, disp ); while ( true ) { int result; @@ -1313,7 +1310,7 @@ namespace cds { namespace container { } template - int try_update_node( Func funcUpdate, node_type * pNode, version_type nVersion, rcu_disposer& disp ) + int try_update_node( int nFlags, Func funcUpdate, node_type * pNode, version_type nVersion, rcu_disposer& disp ) { mapped_type pOld; assert( pNode != nullptr ); @@ -1328,6 +1325,12 @@ namespace cds { namespace container { return update_flags::retry; } + if ( pNode->is_valued( memory_model::memory_order_relaxed ) && !(nFlags & update_flags::allow_update) ) { + m_stat.onInsertFailed(); + return update_flags::failed; + } + + pOld = pNode->value( memory_model::memory_order_relaxed ); mapped_type pVal = funcUpdate( pNode ); if ( pVal == pOld ) diff --git a/tests/unit/print_bronsonavltree_stat.h b/tests/unit/print_bronsonavltree_stat.h index 1a1d39d7..e1c6996c 100644 --- a/tests/unit/print_bronsonavltree_stat.h +++ b/tests/unit/print_bronsonavltree_stat.h @@ -20,6 +20,7 @@ namespace std { << "\t\t m_nFindRetry: " << s.m_nFindRetry.get() << "\n" << "\t\t m_nFindWaitShrinking: " << s.m_nFindWaitShrinking.get() << "\n" << "\t\t m_nInsertSuccess: " << s.m_nInsertSuccess.get() << "\n" + << "\t\t m_nInsertFailed: " << s.m_nInsertFailed.get() << "\n" << "\t\t m_nRelaxedInsertFailed: " << s.m_nRelaxedInsertFailed.get() << "\n" << "\t\t m_nInsertRetry: " << s.m_nInsertRetry.get() << "\n" << "\t\t m_nUpdateWaitShrinking: " << s.m_nUpdateWaitShrinking.get() << "\n"