From: khizmax Date: Mon, 14 Dec 2015 20:17:17 +0000 (+0300) Subject: LazyList refactoring X-Git-Tag: v2.1.0~30 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=d05a0909402369d4a79eb82aed1742a7b227548b;p=libcds.git LazyList refactoring --- diff --git a/cds/intrusive/impl/lazy_list.h b/cds/intrusive/impl/lazy_list.h index 103dae8a..6fe3838d 100644 --- a/cds/intrusive/impl/lazy_list.h +++ b/cds/intrusive/impl/lazy_list.h @@ -238,19 +238,7 @@ namespace cds { namespace intrusive { } }; - class auto_lock_position { - position& m_pos; - public: - auto_lock_position( position& pos ) - : m_pos(pos) - { - pos.lock(); - } - ~auto_lock_position() - { - m_pos.unlock(); - } - }; + typedef std::unique_lock< position > scoped_position_lock; //@endcond protected: @@ -914,7 +902,7 @@ namespace cds { namespace intrusive { while ( true ) { search( pHead, val, pos, key_comparator() ); { - auto_lock_position alp( pos ); + scoped_position_lock alp( pos ); if ( validate( pos.pPred, pos.pCur )) { if ( pos.pCur != &m_Tail && cmp( *node_traits::to_value_ptr( *pos.pCur ), val ) == 0 ) { // failed: key already in list @@ -940,7 +928,7 @@ namespace cds { namespace intrusive { while ( true ) { search( pHead, val, pos, key_comparator() ); { - auto_lock_position alp( pos ); + scoped_position_lock alp( pos ); if ( validate( pos.pPred, pos.pCur )) { if ( pos.pCur != &m_Tail && cmp( *node_traits::to_value_ptr( *pos.pCur ), val ) == 0 ) { // failed: key already in list @@ -966,7 +954,7 @@ namespace cds { namespace intrusive { while ( true ) { search( pHead, val, pos, key_comparator() ); { - auto_lock_position alp( pos ); + scoped_position_lock alp( pos ); if ( validate( pos.pPred, pos.pCur )) { if ( pos.pCur != &m_Tail && cmp( *node_traits::to_value_ptr( *pos.pCur ), val ) == 0 ) { // key already in the list @@ -1001,7 +989,7 @@ namespace cds { namespace intrusive { { int nResult = 0; { - auto_lock_position alp( pos ); + scoped_position_lock alp( pos ); if ( validate( pos.pPred, pos.pCur ) ) { if ( pos.pCur != &m_Tail && cmp( *node_traits::to_value_ptr( *pos.pCur ), val ) == 0 @@ -1035,7 +1023,7 @@ namespace cds { namespace intrusive { { int nResult = 0; { - auto_lock_position alp( pos ); + scoped_position_lock alp( pos ); if ( validate( pos.pPred, pos.pCur )) { if ( pos.pCur != &m_Tail && cmp( *node_traits::to_value_ptr( *pos.pCur ), val ) == 0 ) { // key found diff --git a/cds/intrusive/lazy_list_rcu.h b/cds/intrusive/lazy_list_rcu.h index 0dbe0fd3..ea9ccbe0 100644 --- a/cds/intrusive/lazy_list_rcu.h +++ b/cds/intrusive/lazy_list_rcu.h @@ -168,19 +168,7 @@ namespace cds { namespace intrusive { } }; - class auto_lock_position { - position& m_pos; - public: - auto_lock_position( position& pos ) - : m_pos(pos) - { - pos.lock(); - } - ~auto_lock_position() - { - m_pos.unlock(); - } - }; + typedef std::unique_lock< position > scoped_position_lock; typedef cds::urcu::details::check_deadlock_policy< gc, rcu_check_deadlock> check_deadlock_policy; //@endcond @@ -209,7 +197,7 @@ namespace cds { namespace intrusive { gc::template retire_ptr( node_traits::to_value_ptr( *pNode ) ); } - void link_node( node_type * pNode, node_type * pPred, node_type * pCur ) + static void link_node( node_type * pNode, node_type * pPred, node_type * pCur ) { assert( pPred->m_pNext.load(memory_model::memory_order_relaxed).ptr() == pCur ); @@ -250,7 +238,7 @@ namespace cds { namespace intrusive { assert( m_pNode != nullptr ); node_type * pNode = node_traits::to_node_ptr( m_pNode ); - node_type * pNext = pNode->m_pNext.load(memory_model::memory_order_relaxed).ptr(); + node_type * pNext = pNode->m_pNext.load(memory_model::memory_order_acquire).ptr(); if ( pNext != nullptr ) m_pNode = node_traits::to_value_ptr( pNext ); } @@ -262,7 +250,7 @@ namespace cds { namespace intrusive { // Dummy tail node could not be marked while ( pNode->is_marked() ) - pNode = pNode->m_pNext.load(memory_model::memory_order_relaxed).ptr(); + pNode = pNode->m_pNext.load(memory_model::memory_order_acquire).ptr(); if ( pNode != node_traits::to_node_ptr( m_pNode ) ) m_pNode = node_traits::to_value_ptr( pNode ); @@ -867,7 +855,7 @@ namespace cds { namespace intrusive { assert( pNode != nullptr ); // Hack: convert node_type to value_type. - // In principle, auxiliary node can be non-reducible to value_type + // Actually, an auxiliary node should not be converted to value_type // We assume that comparator can correctly distinguish aux and regular node. return insert_at( pHead, *node_traits::to_value_ptr( pNode ) ); } @@ -878,34 +866,6 @@ namespace cds { namespace intrusive { return insert_at_locked( pHead, val ); } - bool insert_at_locked( node_type * pHead, value_type& val ) - { - // RCU lock should be locked!!! - assert( gc::is_locked() ); - - link_checker::is_empty( node_traits::to_node_ptr( val ) ); - position pos; - key_comparator cmp; - - while ( true ) { - search( pHead, val, pos ); - { - auto_lock_position alp( pos ); - if ( validate( pos.pPred, pos.pCur )) { - if ( pos.pCur != &m_Tail && cmp( *node_traits::to_value_ptr( *pos.pCur ), val ) == 0 ) { - // failed: key already in list - return false; - } - else { - link_node( node_traits::to_node_ptr( val ), pos.pPred, pos.pCur ); - ++m_ItemCounter; - return true; - } - } - } - } - } - template bool insert_at( node_type * pHead, value_type& val, Func f ) { @@ -917,18 +877,17 @@ namespace cds { namespace intrusive { while ( true ) { search( pHead, val, pos ); { - auto_lock_position alp( pos ); + scoped_position_lock sl( pos ); if ( validate( pos.pPred, pos.pCur )) { if ( pos.pCur != &m_Tail && cmp( *node_traits::to_value_ptr( *pos.pCur ), val ) == 0 ) { // failed: key already in list return false; } - else { - link_node( node_traits::to_node_ptr( val ), pos.pPred, pos.pCur ); - f( val ); - ++m_ItemCounter; - return true; - } + + link_node( node_traits::to_node_ptr( val ), pos.pPred, pos.pCur ); + f( val ); + ++m_ItemCounter; + return true; } } } @@ -950,43 +909,6 @@ namespace cds { namespace intrusive { return update_at_locked( pHead, val, func, bAllowInsert ); } - template - std::pair update_at_locked( node_type * pHead, value_type& val, Func func, bool bAllowInsert ) - { - // RCU lock should be locked!!! - assert( gc::is_locked() ); - - position pos; - key_comparator cmp; - - while ( true ) { - search( pHead, val, pos ); - { - auto_lock_position alp( pos ); - if ( validate( pos.pPred, pos.pCur )) { - if ( pos.pCur != &m_Tail && cmp( *node_traits::to_value_ptr( *pos.pCur ), val ) == 0 ) { - // key already in the list - - func( false, *node_traits::to_value_ptr( *pos.pCur ) , val ); - return std::make_pair( iterator( pos.pCur ), false ); - } - else { - // new key - if ( !bAllowInsert ) - return std::make_pair( end(), false ); - - link_checker::is_empty( node_traits::to_node_ptr( val ) ); - - link_node( node_traits::to_node_ptr( val ), pos.pPred, pos.pCur ); - func( true, val, val ); - ++m_ItemCounter; - return std::make_pair( iterator( node_traits::to_node_ptr( val )), true ); - } - } - } - } - } - template std::pair update_at( node_type * pHead, value_type& val, Func func, bool bAllowInsert ) { @@ -1007,7 +929,7 @@ namespace cds { namespace intrusive { rcu_lock l; search( pHead, val, pos ); { - auto_lock_position alp( pos ); + scoped_position_lock alp( pos ); if ( validate( pos.pPred, pos.pCur ) ) { if ( pos.pCur != &m_Tail && cmp( *node_traits::to_value_ptr( *pos.pCur ), val ) == 0 @@ -1045,7 +967,7 @@ namespace cds { namespace intrusive { rcu_lock l; search( pHead, val, pos, cmp ); { - auto_lock_position alp( pos ); + scoped_position_lock alp( pos ); if ( validate( pos.pPred, pos.pCur )) { if ( pos.pCur != &m_Tail && cmp( *node_traits::to_value_ptr( *pos.pCur ), val ) == 0 ) { // key found @@ -1054,9 +976,8 @@ namespace cds { namespace intrusive { --m_ItemCounter; nResult = 1; } - else { + else nResult = -1; - } } } } @@ -1082,7 +1003,7 @@ namespace cds { namespace intrusive { bool erase_at( node_type * pHead, Q const& val, Compare cmp ) { position pos; - return erase_at( pHead, val, cmp, [](value_type const &){}, pos ); + return erase_at( pHead, val, cmp, [](value_type const&){}, pos ); } template @@ -1095,7 +1016,7 @@ namespace cds { namespace intrusive { search( pHead, val, pos, cmp ); int nResult = 0; { - auto_lock_position alp( pos ); + scoped_position_lock alp( pos ); if ( validate( pos.pPred, pos.pCur )) { if ( pos.pCur != &m_Tail && cmp( *node_traits::to_value_ptr( *pos.pCur ), val ) == 0 ) { // key found @@ -1206,6 +1127,73 @@ namespace cds { namespace intrusive { } //@endcond + + private: + //@cond + bool insert_at_locked( node_type * pHead, value_type& val ) + { + // RCU lock should be locked!!! + assert( gc::is_locked() ); + + link_checker::is_empty( node_traits::to_node_ptr( val )); + position pos; + key_comparator cmp; + + while ( true ) { + search( pHead, val, pos ); + { + scoped_position_lock alp( pos ); + if ( validate( pos.pPred, pos.pCur ) ) { + if ( pos.pCur != &m_Tail && cmp( *node_traits::to_value_ptr( *pos.pCur ), val ) == 0 ) { + // failed: key already in list + return false; + } + + link_node( node_traits::to_node_ptr( val ), pos.pPred, pos.pCur ); + ++m_ItemCounter; + return true; + } + } + } + } + + template + std::pair update_at_locked( node_type * pHead, value_type& val, Func func, bool bAllowInsert ) + { + // RCU lock should be locked!!! + assert( gc::is_locked() ); + + position pos; + key_comparator cmp; + + while ( true ) { + search( pHead, val, pos ); + { + scoped_position_lock alp( pos ); + if ( validate( pos.pPred, pos.pCur ) ) { + if ( pos.pCur != &m_Tail && cmp( *node_traits::to_value_ptr( *pos.pCur ), val ) == 0 ) { + // key already in the list + + func( false, *node_traits::to_value_ptr( *pos.pCur ), val ); + return std::make_pair( iterator( pos.pCur ), false ); + } + else { + // new key + if ( !bAllowInsert ) + return std::make_pair( end(), false ); + + link_checker::is_empty( node_traits::to_node_ptr( val ) ); + + link_node( node_traits::to_node_ptr( val ), pos.pPred, pos.pCur ); + func( true, val, val ); + ++m_ItemCounter; + return std::make_pair( iterator( node_traits::to_node_ptr( val ) ), true ); + } + } + } + } + } + //@endcond }; }} // namespace cds::intrusive