From 7029b34e759d463d1b27962f9ccbd0769402a386 Mon Sep 17 00:00:00 2001 From: khizmax Date: Mon, 17 Nov 2014 00:33:09 +0300 Subject: [PATCH] Small changes in HP GC --- cds/gc/details/hp.h | 8 ++--- cds/gc/details/retired_ptr.h | 6 ++-- cds/gc/impl/hp_decl.h | 18 +++++------ cds/gc/impl/hp_impl.h | 1 - src/hp_gc.cpp | 61 +++++++++++++++++++----------------- 5 files changed, 48 insertions(+), 46 deletions(-) diff --git a/cds/gc/details/hp.h b/cds/gc/details/hp.h index 0bc258f3..1c254518 100644 --- a/cds/gc/details/hp.h +++ b/cds/gc/details/hp.h @@ -125,7 +125,7 @@ namespace cds { public: /// Iterator - typedef retired_vector_impl::iterator iterator; + typedef retired_vector_impl::iterator iterator; /// Constructor retired_vector( const cds::gc::hp::GarbageCollector& HzpMgr ) CDS_NOEXCEPT; // inline @@ -283,9 +283,9 @@ namespace cds { /// Internal list of cds::gc::hp::details::hp_record struct hplist_node : public details::hp_record { - hplist_node * m_pNextNode ; ///< next hazard ptr record in list - atomics::atomic m_idOwner ; ///< Owner thread id; 0 - the record is free (not owned) - atomics::atomic m_bFree ; ///< true if record if free (not owned) + hplist_node * m_pNextNode; ///< next hazard ptr record in list + atomics::atomic m_idOwner; ///< Owner thread id; 0 - the record is free (not owned) + atomics::atomic m_bFree; ///< true if record if free (not owned) hplist_node( const GarbageCollector& HzpMgr ) : hp_record( HzpMgr ), diff --git a/cds/gc/details/retired_ptr.h b/cds/gc/details/retired_ptr.h index 5bb6f4f6..850451e1 100644 --- a/cds/gc/details/retired_ptr.h +++ b/cds/gc/details/retired_ptr.h @@ -20,8 +20,8 @@ namespace cds { namespace gc { /// Pointer type typedef void * pointer; - pointer m_p ; ///< retired pointer - free_retired_ptr_func m_funcFree ; ///< pointer to the destructor function + pointer m_p; ///< retired pointer + free_retired_ptr_func m_funcFree; ///< pointer to the destructor function /// Comparison of two retired pointers static bool less( const retired_ptr& p1, const retired_ptr& p2 ) CDS_NOEXCEPT @@ -49,7 +49,7 @@ namespace cds { namespace gc { {} /// Assignment operator - retired_ptr& operator =( const retired_ptr& s) CDS_NOEXCEPT + retired_ptr& operator =( retired_ptr const& s) CDS_NOEXCEPT { m_p = s.m_p; m_funcFree = s.m_funcFree; diff --git a/cds/gc/impl/hp_decl.h b/cds/gc/impl/hp_decl.h index 1fd30d39..4a0593a6 100644 --- a/cds/gc/impl/hp_decl.h +++ b/cds/gc/impl/hp_decl.h @@ -265,8 +265,8 @@ namespace cds { namespace gc { { T pRet; do { - pRet = assign( nIndex, toGuard.load(atomics::memory_order_acquire) ); - } while ( pRet != toGuard.load(atomics::memory_order_relaxed)); + pRet = assign( nIndex, toGuard.load(atomics::memory_order_relaxed) ); + } while ( pRet != toGuard.load(atomics::memory_order_acquire)); return pRet; } @@ -293,8 +293,8 @@ namespace cds { namespace gc { { T pRet; do { - assign( nIndex, f( pRet = toGuard.load(atomics::memory_order_acquire) )); - } while ( pRet != toGuard.load(atomics::memory_order_relaxed)); + assign( nIndex, f( pRet = toGuard.load(atomics::memory_order_relaxed) )); + } while ( pRet != toGuard.load(atomics::memory_order_acquire)); return pRet; } @@ -420,19 +420,19 @@ namespace cds { namespace gc { } /// Returns max Hazard Pointer count - size_t max_hazard_count() const + static size_t max_hazard_count() { return hp::GarbageCollector::instance().getHazardPointerCount(); } /// Returns max count of thread - size_t max_thread_count() const + static size_t max_thread_count() { return hp::GarbageCollector::instance().getMaxThreadCount(); } /// Returns capacity of retired pointer array - size_t retired_array_capacity() const + static size_t retired_array_capacity() { return hp::GarbageCollector::instance().getMaxRetiredPtrCount(); } @@ -499,13 +499,13 @@ namespace cds { namespace gc { static void retire( T * p ) ; // inline in hp_impl.h /// Get current scan strategy - scan_type getScanType() const + static scan_type getScanType() { return static_cast( hp::GarbageCollector::instance().getScanType()); } /// Set current scan strategy - void setScanType( + static void setScanType( scan_type nScanType ///< new scan strategy ) { diff --git a/cds/gc/impl/hp_impl.h b/cds/gc/impl/hp_impl.h index 1c43b4a0..870b348f 100644 --- a/cds/gc/impl/hp_impl.h +++ b/cds/gc/impl/hp_impl.h @@ -50,7 +50,6 @@ namespace cds { namespace gc { cds::threading::getGC().scan(); } - }} // namespace cds::gc //@endcond diff --git a/src/hp_gc.cpp b/src/hp_gc.cpp index 4899dd4d..f256dee7 100644 --- a/src/hp_gc.cpp +++ b/src/hp_gc.cpp @@ -189,7 +189,7 @@ namespace cds { namespace gc { details::retired_vector::iterator itRetired = arrRetired.begin(); details::retired_vector::iterator itRetiredEnd = arrRetired.end(); // arrRetired is not a std::vector! - // clear is just set up item counter to 0, the items is not destroying + // clear() is just set up item counter to 0, the items is not destroyed arrRetired.clear(); std::vector< void * >::iterator itBegin = plist.begin(); @@ -217,8 +217,8 @@ namespace cds { namespace gc { // LSB is used for marking pointers that cannot be deleted yet details::retired_vector::iterator itRetired = pRec->m_arrRetired.begin(); details::retired_vector::iterator itRetiredEnd = pRec->m_arrRetired.end(); - for ( details::retired_vector::iterator it = itRetired; it != itRetiredEnd; ++it ) { - if ( reinterpret_cast(it->m_p) & 1 ) { + for ( auto it = itRetired; it != itRetiredEnd; ++it ) { + if ( reinterpret_cast(it->m_p) & 1 ) { // found a pointer with LSB bit set - use classic_scan classic_scan( pRec ); return; @@ -229,40 +229,43 @@ namespace cds { namespace gc { std::sort( itRetired, itRetiredEnd, cds::gc::details::retired_ptr::less ); // Search guarded pointers in retired array - - hplist_node * pNode = m_pListHead.load(atomics::memory_order_acquire); - - while ( pNode ) { - for ( size_t i = 0; i < m_nHazardPointerCount; ++i ) { - void * hptr = pNode->m_hzp[i]; - if ( hptr ) { - details::retired_ptr dummyRetired; - dummyRetired.m_p = hptr; - details::retired_vector::iterator it = std::lower_bound( itRetired, itRetiredEnd, dummyRetired, cds::gc::details::retired_ptr::less ); - if ( it != itRetiredEnd && it->m_p == hptr ) { - // Mark retired pointer as guarded - it->m_p = reinterpret_cast(reinterpret_cast(it->m_p ) | 1); + hplist_node * pNode = m_pListHead.load( atomics::memory_order_acquire ); + + { + details::retired_ptr dummyRetired; + while ( pNode ) { + for ( size_t i = 0; i < m_nHazardPointerCount; ++i ) { + void * hptr = pNode->m_hzp[i]; + if ( hptr ) { + dummyRetired.m_p = hptr; + details::retired_vector::iterator it = std::lower_bound( itRetired, itRetiredEnd, dummyRetired, cds::gc::details::retired_ptr::less ); + if ( it != itRetiredEnd && it->m_p == hptr ) { + // Mark retired pointer as guarded + it->m_p = reinterpret_cast(reinterpret_cast(it->m_p) | 1); + } } } + pNode = pNode->m_pNextNode; } - pNode = pNode->m_pNextNode; } // Move all marked pointers to head of array - details::retired_vector::iterator itInsert = itRetired; - for ( details::retired_vector::iterator it = itRetired; it != itRetiredEnd; ++it ) { - if ( reinterpret_cast(it->m_p) & 1 ) { - it->m_p = reinterpret_cast(reinterpret_cast(it->m_p ) & ~1); - *itInsert = *it; - ++itInsert; - CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_DeferredNode ); - } - else { - // Retired pointer may be freed - DeletePtr( *it ); + { + details::retired_vector::iterator itInsert = itRetired; + for ( auto it = itRetired; it != itRetiredEnd; ++it ) { + if ( reinterpret_cast(it->m_p) & 1 ) { + it->m_p = reinterpret_cast(reinterpret_cast(it->m_p) & ~1); + *itInsert = *it; + ++itInsert; + CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_DeferredNode ); + } + else { + // Retired pointer may be freed + DeletePtr( *it ); + } } + pRec->m_arrRetired.size( itInsert - itRetired ); } - pRec->m_arrRetired.size( itInsert - itRetired ); } void GarbageCollector::HelpScan( details::hp_record * pThis ) -- 2.34.1