X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=cds%2Fintrusive%2Fimpl%2Fiterable_list.h;h=fe85cc98ff13a56f2021ba79143039681f7eda28;hb=40a5453909484139fc270121370575632c8e9e5c;hp=ccc50be6d1f7ea0f97d5a53373f3da31517ac3e8;hpb=f31988b031453d7fdf7fe212f966554fa558af3e;p=libcds.git diff --git a/cds/intrusive/impl/iterable_list.h b/cds/intrusive/impl/iterable_list.h index ccc50be6..fe85cc98 100644 --- a/cds/intrusive/impl/iterable_list.h +++ b/cds/intrusive/impl/iterable_list.h @@ -5,7 +5,7 @@ Source code repo: http://github.com/khizmax/libcds/ Download: http://sourceforge.net/projects/libcds/files/ - + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -160,6 +160,7 @@ namespace cds { namespace intrusive { //@endcond protected: + //@cond typedef atomics::atomic< node_type* > atomic_node_ptr; ///< Atomic node pointer typedef atomic_node_ptr auxiliary_head; ///< Auxiliary head type (for split-list support) @@ -167,7 +168,6 @@ namespace cds { namespace intrusive { item_counter m_ItemCounter; ///< Item counter mutable stat m_Stat; ///< Internal statistics - //@cond typedef cds::details::Allocator< node_type, node_allocator > cxx_node_allocator; /// Position pointer for item search @@ -190,35 +190,32 @@ namespace cds { namespace intrusive { protected: node_type* m_pNode; - value_type* m_pVal; - typename gc::Guard m_Guard; // for m_pVal + typename gc::Guard m_Guard; // data guard void next() { while ( m_pNode ) { - m_pNode = m_pNode->next.load( memory_model::memory_order_relaxed ); - if ( !m_pNode ) + m_pNode = m_pNode->next.load( memory_model::memory_order_acquire ); + if ( !m_pNode ) { + m_Guard.clear(); break; - m_pVal = m_Guard.protect( m_pNode->data ); - if ( m_pVal ) + } + if ( m_Guard.protect( m_pNode->data )) break; } } explicit iterator_type( atomic_node_ptr const& pNode ) - : m_pNode( pNode.load( memory_model::memory_order_relaxed )) - , m_pVal( nullptr ) + : m_pNode( pNode.load( memory_model::memory_order_acquire )) { if ( m_pNode ) { - m_pVal = m_Guard.protect( m_pNode->data ); - if ( !m_pVal ) + if ( !m_Guard.protect( m_pNode->data )) next(); } } iterator_type( node_type* pNode, value_type* pVal ) : m_pNode( pNode ) - , m_pVal( pVal ) { if ( m_pNode ) { assert( pVal != nullptr ); @@ -232,25 +229,23 @@ namespace cds { namespace intrusive { iterator_type() : m_pNode( nullptr ) - , m_pVal( nullptr ) {} iterator_type( iterator_type const& src ) : m_pNode( src.m_pNode ) - , m_pVal( src.m_pVal ) { - m_Guard.assign( m_pVal ); + m_Guard.copy( src.m_Guard ); } value_ptr operator ->() const { - return m_pVal; + return m_Guard.template get(); } value_ref operator *() const { - assert( m_pVal != nullptr ); - return *m_pVal; + assert( m_Guard.get_native() != nullptr ); + return *m_Guard.template get(); } /// Pre-increment @@ -263,8 +258,7 @@ namespace cds { namespace intrusive { iterator_type& operator = (iterator_type const& src) { m_pNode = src.m_pNode; - m_pVal = src.m_pVal; - m_Guard.assign( m_pVal ); + m_Guard.copy( src.m_Guard ); return *this; } @@ -276,7 +270,7 @@ namespace cds { namespace intrusive { template bool operator !=(iterator_type const& i ) const { - return m_pNode != i.m_pNode; + return !( *this == i ); } }; //@endcond @@ -591,7 +585,7 @@ namespace cds { namespace intrusive { ord_list theList; // ... { - ord_list::guarded_ptr gp(theList.extract( 5 )); + ord_list::guarded_ptr gp( theList.extract( 5 )); if ( gp ) { // Deal with gp // ... @@ -603,9 +597,7 @@ namespace cds { namespace intrusive { template guarded_ptr extract( Q const& key ) { - guarded_ptr gp; - extract_at( m_pHead, gp.guard(), key, key_comparator()); - return gp; + return extract_at( m_pHead, key, key_comparator()); } /// Extracts the item using compare functor \p pred @@ -621,9 +613,7 @@ namespace cds { namespace intrusive { guarded_ptr extract_with( Q const& key, Less pred ) { CDS_UNUSED( pred ); - guarded_ptr gp; - extract_at( m_pHead, gp.guard(), key, cds::opt::details::make_comparator_from_less()); - return gp; + return extract_at( m_pHead, key, cds::opt::details::make_comparator_from_less()); } /// Finds \p key in the list @@ -760,9 +750,7 @@ namespace cds { namespace intrusive { template guarded_ptr get( Q const& key ) const { - guarded_ptr gp; - get_at( m_pHead, gp.guard(), key, key_comparator()); - return gp; + return get_at( m_pHead, key, key_comparator()); } /// Finds the \p key and return the item found @@ -778,9 +766,7 @@ namespace cds { namespace intrusive { guarded_ptr get_with( Q const& key, Less pred ) const { CDS_UNUSED( pred ); - guarded_ptr gp; - get_at( m_pHead, gp.guard(), key, cds::opt::details::make_comparator_from_less()); - return gp; + return get_at( m_pHead, key, cds::opt::details::make_comparator_from_less()); } /// Clears the list (thread safe, not atomic) @@ -995,16 +981,16 @@ namespace cds { namespace intrusive { } template - bool extract_at( atomic_node_ptr& refHead, typename guarded_ptr::native_guard& dest, Q const& val, Compare cmp ) + guarded_ptr extract_at( atomic_node_ptr& refHead, Q const& val, Compare cmp ) { position pos; back_off bkoff; while ( search( refHead, val, pos, cmp )) { if ( unlink_node( pos )) { - dest.set( pos.pFound ); --m_ItemCounter; m_Stat.onEraseSuccess(); - return true; + assert( pos.pFound != nullptr ); + return guarded_ptr( std::move( pos.guard )); } else bkoff(); @@ -1013,7 +999,7 @@ namespace cds { namespace intrusive { } m_Stat.onEraseFailed(); - return false; + return guarded_ptr(); } template @@ -1060,17 +1046,16 @@ namespace cds { namespace intrusive { } template - bool get_at( atomic_node_ptr const& refHead, typename guarded_ptr::native_guard& guard, Q const& val, Compare cmp ) const + guarded_ptr get_at( atomic_node_ptr const& refHead, Q const& val, Compare cmp ) const { position pos; if ( search( refHead, val, pos, cmp )) { - guard.set( pos.pFound ); m_Stat.onFindSuccess(); - return true; + return guarded_ptr( std::move( pos.guard )); } m_Stat.onFindFailed(); - return false; + return guarded_ptr(); } //@endcond