Small changes in HP GC
authorkhizmax <libcds.dev@gmail.com>
Sun, 16 Nov 2014 21:33:09 +0000 (00:33 +0300)
committerkhizmax <libcds.dev@gmail.com>
Sun, 16 Nov 2014 21:33:09 +0000 (00:33 +0300)
cds/gc/details/hp.h
cds/gc/details/retired_ptr.h
cds/gc/impl/hp_decl.h
cds/gc/impl/hp_impl.h
src/hp_gc.cpp

index 0bc258f35fe544c06bd37f86a6171abec718d91c..1c2545189d9118f0c8cd426c0fd3867e90a51d80 100644 (file)
@@ -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<OS::ThreadId>    m_idOwner   ; ///< Owner thread id; 0 - the record is free (not owned)
-                atomics::atomic<bool>            m_bFree     ; ///< true if record if free (not owned)
+                hplist_node *                    m_pNextNode; ///< next hazard ptr record in list
+                atomics::atomic<OS::ThreadId>    m_idOwner;   ///< Owner thread id; 0 - the record is free (not owned)
+                atomics::atomic<bool>            m_bFree;     ///< true if record if free (not owned)
 
                 hplist_node( const GarbageCollector& HzpMgr )
                     : hp_record( HzpMgr ),
index 5bb6f4f6ba82d3d2cda01e5c8082a1f279d858ba..850451e16adfd6b7f2028510c43ad1b850b7e5e6 100644 (file)
@@ -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;
index 1fd30d3987ed765ba1d84a4c95b7186bd531d06d..4a0593a6cddc547e9edb65afdd572fed0112da22 100644 (file)
@@ -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<scan_type>( hp::GarbageCollector::instance().getScanType());
         }
 
         /// Set current scan strategy
-        void setScanType(
+        static void setScanType(
             scan_type nScanType     ///< new scan strategy
         )
         {
index 1c43b4a01f4e12596589b5158d90a895e2924806..870b348f26e10444b7cea343159968617fc85d1d 100644 (file)
@@ -50,7 +50,6 @@ namespace cds { namespace gc {
         cds::threading::getGC<HP>().scan();
     }
 
-
 }} // namespace cds::gc
 //@endcond
 
index 4899dd4d748af930f680f02d470bf54af43e0e75..f256dee77405acabd8085c509a902e55ba91e7a9 100644 (file)
@@ -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<ptr_atomic_t>(it->m_p) & 1 ) {
+            for ( auto it = itRetired; it != itRetiredEnd; ++it ) {
+                if ( reinterpret_cast<uintptr_t>(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<void *>(reinterpret_cast<ptr_atomic_t>(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<void *>(reinterpret_cast<uintptr_t>(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<ptr_atomic_t>(it->m_p) & 1 ) {
-                    it->m_p = reinterpret_cast<void *>(reinterpret_cast<ptr_atomic_t>(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<uintptr_t>(it->m_p) & 1 ) {
+                        it->m_p = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(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 )