From: khizmax Date: Sat, 15 Nov 2014 12:48:06 +0000 (+0300) Subject: Hazard Pointer refactoring X-Git-Tag: v2.0.0~88 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=libcds.git;a=commitdiff_plain;h=39b87766c998a31456e5fbfd2b48ebc7a5d42167 Hazard Pointer refactoring --- diff --git a/cds/details/bounded_array.h b/cds/details/bounded_array.h index 97a783ad..7bd98fe1 100644 --- a/cds/details/bounded_array.h +++ b/cds/details/bounded_array.h @@ -198,7 +198,7 @@ namespace cds { } /// Returns pointer to the first item in the array - value_type * top() + value_type * top() CDS_NOEXCEPT { return m_arr; } diff --git a/cds/gc/details/retired_ptr.h b/cds/gc/details/retired_ptr.h index 91b490c8..5bb6f4f6 100644 --- a/cds/gc/details/retired_ptr.h +++ b/cds/gc/details/retired_ptr.h @@ -24,32 +24,32 @@ namespace cds { namespace gc { 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 ) + static bool less( const retired_ptr& p1, const retired_ptr& p2 ) CDS_NOEXCEPT { return p1.m_p < p2.m_p; } /// Default ctor initializes pointer to \p nullptr - retired_ptr() + retired_ptr() CDS_NOEXCEPT : m_p( nullptr ) , m_funcFree( nullptr ) {} /// Ctor - retired_ptr( pointer p, free_retired_ptr_func func ) + retired_ptr( pointer p, free_retired_ptr_func func ) CDS_NOEXCEPT : m_p( p ), m_funcFree( func ) {} /// Typecasting ctor template - retired_ptr( T * p, void (* pFreeFunc)(T *)) + retired_ptr( T * p, void (* pFreeFunc)(T *)) CDS_NOEXCEPT : m_p( reinterpret_cast( p ) ) , m_funcFree( reinterpret_cast< free_retired_ptr_func >( pFreeFunc )) {} /// Assignment operator - retired_ptr& operator =( const retired_ptr& s) + retired_ptr& operator =( const retired_ptr& s) CDS_NOEXCEPT { m_p = s.m_p; m_funcFree = s.m_funcFree; @@ -69,23 +69,21 @@ namespace cds { namespace gc { }; //@cond - static inline bool operator <( const retired_ptr& p1, const retired_ptr& p2 ) + static inline bool operator <( const retired_ptr& p1, const retired_ptr& p2 ) CDS_NOEXCEPT { return retired_ptr::less( p1, p2 ); } - static inline bool operator ==( const retired_ptr& p1, const retired_ptr& p2 ) + static inline bool operator ==( const retired_ptr& p1, const retired_ptr& p2 ) CDS_NOEXCEPT { return p1.m_p == p2.m_p; } - static inline bool operator !=( const retired_ptr& p1, const retired_ptr& p2 ) + static inline bool operator !=( const retired_ptr& p1, const retired_ptr& p2 ) CDS_NOEXCEPT { return !(p1 == p2); } //@endcond - - } // namespace details }} // namespace cds::gc diff --git a/cds/gc/hp/details/hp_alloc.h b/cds/gc/hp/details/hp_alloc.h index b706850f..05cc6260 100644 --- a/cds/gc/hp/details/hp_alloc.h +++ b/cds/gc/hp/details/hp_alloc.h @@ -5,12 +5,15 @@ #include #include -#include #include //@cond namespace cds { namespace gc { namespace hp { + // forwards + class GarbageCollector; + class ThreadGC; + /// Hazard Pointer schema implementation details namespace details { @@ -18,15 +21,11 @@ namespace cds { /** It is unsafe to use this class directly. Instead, the AutoHPGuard class should be used. - - Template parameter: - \li HazardPointer - type of hazard pointer. It is \ref hazard_pointer for Michael's Hazard Pointer reclamation schema */ - template - class HPGuardT: protected atomics::atomic + class hp_guard : protected atomics::atomic < hazard_pointer > { public: - typedef HazardPointer hazard_ptr ; ///< Hazard pointer type + typedef hazard_pointer hazard_ptr; ///< Hazard pointer type private: //@cond typedef atomics::atomic base_class; @@ -34,30 +33,30 @@ namespace cds { protected: //@cond - template friend class HPAllocator; + template friend class hp_allocator; //@endcond public: - HPGuardT() CDS_NOEXCEPT + hp_guard() CDS_NOEXCEPT : base_class( nullptr ) {} - ~HPGuardT() CDS_NOEXCEPT + ~hp_guard() CDS_NOEXCEPT {} /// Sets HP value. Guards pointer \p p from reclamation. /** Storing has release semantics. - */ - template - T * operator =( T * p ) CDS_NOEXCEPT + */ + template + T * operator =(T * p) CDS_NOEXCEPT { // We use atomic store with explicit memory order because other threads may read this hazard pointer concurrently - base_class::store( reinterpret_cast(p), atomics::memory_order_release ); + set( p ); return p; } //@cond - std::nullptr_t operator=( std::nullptr_t ) CDS_NOEXCEPT + std::nullptr_t operator=(std::nullptr_t) CDS_NOEXCEPT { clear(); return nullptr; @@ -77,26 +76,28 @@ namespace cds { /** Loading has acquire semantics */ - hazard_ptr get() const CDS_NOEXCEPT + hazard_ptr get( atomics::memory_order order = atomics::memory_order_acquire ) const CDS_NOEXCEPT + { + return base_class::load( order ); + } + + template + void set( T * p, atomics::memory_order order = atomics::memory_order_release ) CDS_NOEXCEPT { - return base_class::load( atomics::memory_order_acquire ); + base_class::store( reinterpret_cast(p), order ); } /// Clears HP /** Clearing has relaxed semantics. */ - void clear() CDS_NOEXCEPT + void clear( atomics::memory_order order = atomics::memory_order_relaxed ) CDS_NOEXCEPT { // memory order is not necessary here - base_class::store( nullptr, atomics::memory_order_relaxed ); - //CDS_COMPILER_RW_BARRIER; + base_class::store( nullptr, order ); } }; - /// Specialization of HPGuardT for hazard_pointer type - typedef HPGuardT HPGuard; - /// Array of hazard pointers. /** Array of hazard-pointer. Placing a pointer into this array guards the pointer against reclamation. @@ -105,39 +106,38 @@ namespace cds { It is unsafe to use this class directly. Instead, the AutoHPArray should be used. - While creating the object of HPArray class an array of size \p Count of hazard pointers is reserved by + While creating the object of \p hp_array class an array of size \p Count of hazard pointers is reserved by the HP Manager of current thread. The object's destructor cleans all of reserved hazard pointer and returns reserved HP to the HP pool of ThreadGC. Usually, it is not necessary to create an object of this class. The object of class ThreadGC contains - the HPArray object and implements interface for HP setting and freeing. + the \p hp_array object and implements interface for HP setting and freeing. Template parameter: - \li HazardPointer - type of hazard pointer. It is hazard_pointer usually \li Count - capacity of array */ - template - class HPArrayT + template + class hp_array { public: - typedef HazardPointer hazard_ptr_type ; ///< Hazard pointer type - typedef HPGuardT atomic_hazard_ptr ; ///< Element type of the array - static const size_t c_nCapacity = Count ; ///< Capacity of the array + typedef hazard_pointer hazard_ptr_type; ///< Hazard pointer type + typedef hp_guard atomic_hazard_ptr; ///< Element type of the array + static CDS_CONSTEXPR const size_t c_nCapacity = Count ; ///< Capacity of the array private: //@cond atomic_hazard_ptr * m_arr ; ///< Hazard pointer array of size = \p Count - template friend class HPAllocator; + template friend class hp_allocator; //@endcond public: /// Constructs uninitialized array. - HPArrayT() CDS_NOEXCEPT + hp_array() CDS_NOEXCEPT {} /// Destructs object - ~HPArrayT() CDS_NOEXCEPT + ~hp_array() CDS_NOEXCEPT {} /// Returns max count of hazard pointer for this array @@ -175,9 +175,6 @@ namespace cds { } }; - /// Specialization of HPArrayT class for hazard_pointer type - template using HPArray = HPArrayT; - /// Allocator of hazard pointers for the thread /** The hazard pointer array is the free-list of unused hazard pointer for the thread. @@ -187,18 +184,17 @@ namespace cds { Each allocator object is thread-private. Template parameters: - \li HazardPointer - type of hazard pointer (hazard_pointer usually) \li Allocator - memory allocator class, default is \ref CDS_DEFAULT_ALLOCATOR This helper class should not be used directly. */ - template < typename HazardPointer, class Allocator = CDS_DEFAULT_ALLOCATOR > - class HPAllocator + template + class hp_allocator { public: - typedef HazardPointer hazard_ptr_type ; ///< type of hazard pointer - typedef HPGuardT atomic_hazard_ptr ; ///< Atomic hazard pointer type - typedef Allocator allocator_type ; ///< allocator type + typedef hazard_pointer hazard_ptr_type; ///< type of hazard pointer + typedef hp_guard atomic_hazard_ptr; ///< Atomic hazard pointer type + typedef Allocator allocator_type; ///< allocator type private: //@cond @@ -212,7 +208,7 @@ namespace cds { public: /// Default ctor - explicit HPAllocator( + explicit hp_allocator( size_t nCapacity ///< max count of hazard pointer per thread ) : m_arrHazardPtr( alloc_array( nCapacity ) ) @@ -222,7 +218,7 @@ namespace cds { } /// Dtor - ~HPAllocator() + ~hp_allocator() { allocator_impl().Delete( m_arrHazardPtr, capacity() ); } @@ -268,7 +264,7 @@ namespace cds { Returns initialized object \p arr */ template - void alloc( HPArrayT& arr ) CDS_NOEXCEPT + void alloc( hp_array& arr ) CDS_NOEXCEPT { assert( m_nTop >= Count ); m_nTop -= Count; @@ -280,7 +276,7 @@ namespace cds { Frees the array of hazard pointers allocated by previous call \p this->alloc. */ template - void free( const HPArrayT& arr ) CDS_NOEXCEPT + void free( hp_array const& arr ) CDS_NOEXCEPT { assert( m_nTop + Count <= capacity()); for ( size_t i = m_nTop; i < m_nTop + Count; ++i ) diff --git a/cds/gc/hp/details/hp_fwd.h b/cds/gc/hp/details/hp_fwd.h deleted file mode 100644 index 9b7fcbdf..00000000 --- a/cds/gc/hp/details/hp_fwd.h +++ /dev/null @@ -1,15 +0,0 @@ -//$$CDS-header$$ - -#ifndef __CDS_GC_HP_DETAILS_HP_FWD_H -#define __CDS_GC_HP_DETAILS_HP_FWD_H - -namespace cds { - namespace gc { namespace hp { - - // forward declarations - class GarbageCollector; - class ThreadGC; - } } -} - -#endif // #ifndef __CDS_GC_HP_DETAILS_HP_FWD_H diff --git a/cds/gc/hp/details/hp_inline.h b/cds/gc/hp/details/hp_inline.h index 741d7340..7142b780 100644 --- a/cds/gc/hp/details/hp_inline.h +++ b/cds/gc/hp/details/hp_inline.h @@ -9,12 +9,12 @@ namespace cds { /************************************************************************/ /* INLINES */ /************************************************************************/ - inline retired_vector::retired_vector( const cds::gc::hp::GarbageCollector& HzpMgr ) + inline retired_vector::retired_vector( const cds::gc::hp::GarbageCollector& HzpMgr ) CDS_NOEXCEPT : m_arr( HzpMgr.getMaxRetiredPtrCount() ), m_nSize(0) {} - inline HPRec::HPRec( const cds::gc::hp::GarbageCollector& HzpMgr ) + inline hp_record::hp_record( const cds::gc::hp::GarbageCollector& HzpMgr ) : m_hzp( HzpMgr.getHazardPointerCount() ), m_arrRetired( HzpMgr ) {} diff --git a/cds/gc/hp/details/hp_retired.h b/cds/gc/hp/details/hp_retired.h deleted file mode 100644 index ec0bacdb..00000000 --- a/cds/gc/hp/details/hp_retired.h +++ /dev/null @@ -1,86 +0,0 @@ -//$$CDS-header$$ - -#ifndef __CDS_GC_HP_DETAILS_HP_RETIRED_H -#define __CDS_GC_HP_DETAILS_HP_RETIRED_H - -#include -#include - -#include - -namespace cds { - namespace gc{ namespace hp { namespace details { - - /// Retired pointer - typedef cds::gc::details::retired_ptr retired_ptr; - - /// Array of retired pointers - /** - The vector of retired pointer ready to delete. - - The Hazard Pointer schema is build on thread-static arrays. For each HP-enabled thread the HP manager allocates - array of retired pointers. The array belongs to the thread: owner thread writes to the array, other threads - just read it. - */ - class retired_vector { - /// Underlying vector implementation - typedef cds::details::bounded_array retired_vector_impl; - - retired_vector_impl m_arr ; ///< the array of retired pointers - size_t m_nSize ; ///< Current size of \p m_arr - - public: - /// Iterator - typedef retired_vector_impl::iterator iterator; - - /// Constructor - retired_vector( const cds::gc::hp::GarbageCollector& HzpMgr ); // inline - ~retired_vector() - {} - - /// Vector capacity. - /** - The capacity is constant for any thread. It is defined by cds::gc::hp::GarbageCollector. - */ - size_t capacity() const { return m_arr.capacity(); } - - /// Current vector size (count of retired pointers in the vector) - size_t size() const { return m_nSize; } - - /// Set vector size. Uses internally - void size( size_t nSize ) - { - assert( nSize <= capacity() ); - m_nSize = nSize; - } - - /// Pushes retired pointer to the vector - void push( const retired_ptr& p ) - { - assert( m_nSize < capacity() ); - m_arr[ m_nSize ] = p; - ++m_nSize; - } - - /// Checks if the vector is full (size() == capacity() ) - bool isFull() const - { - return m_nSize >= capacity(); - } - - /// Begin iterator - iterator begin() { return m_arr.begin(); } - /// End iterator - iterator end() { return m_arr.begin() + m_nSize ; } - - /// Clears the vector. After clearing, size() == 0 - void clear() - { - m_nSize = 0; - } - }; - - } } } // namespace gc::hp::details -} // namespace cds - -#endif // #ifndef __CDS_GC_HP_DETAILS_HP_RETIRED_H diff --git a/cds/gc/hp/details/hp_type.h b/cds/gc/hp/details/hp_type.h index 853f5e1a..2f22ebd4 100644 --- a/cds/gc/hp/details/hp_type.h +++ b/cds/gc/hp/details/hp_type.h @@ -3,7 +3,7 @@ #ifndef __CDS_GC_HP_DETAILS_HP_TYPE_H #define __CDS_GC_HP_DETAILS_HP_TYPE_H -#include +#include // free_retired_ptr_func namespace cds { namespace gc { diff --git a/cds/gc/hp/hp.h b/cds/gc/hp/hp.h index c2af861b..9124850a 100644 --- a/cds/gc/hp/hp.h +++ b/cds/gc/hp/hp.h @@ -3,12 +3,12 @@ #ifndef __CDS_GC_HP_HP_H #define __CDS_GC_HP_HP_H -#include #include #include -#include +#include + +#include #include -#include #if CDS_COMPILER == CDS_COMPILER_MSVC # pragma warning(push) @@ -88,30 +88,116 @@ namespace cds { - [2003] Maged M.Michael "Hazard Pointers: Safe memory reclamation for lock-free objects" - [2004] Andrei Alexandrescy, Maged Michael "Lock-free Data Structures with Hazard Pointers" - - The cds::gc::hp namespace and its members are internal representation of Hazard Pointer GC and should not be used directly. - Use cds::gc::HP class in your code. + The \p cds::gc::hp namespace and its members are internal representation of Hazard Pointer GC and should not be used directly. + Use \p cds::gc::HP class in your code. Hazard Pointer garbage collector is a singleton. The main user-level part of Hazard Pointer schema is GC class and its nested classes. Before use any HP-related class you must initialize HP garbage collector - by contructing cds::gc::HP object in beginning of your main(). - See cds::gc::HP class for explanation. + by contructing \p cds::gc::HP object in beginning of your \p main(). + See \p cds::gc::HP class for explanation. */ namespace hp { + // forwards + class GarbageCollector; + class ThreadGC; + namespace details { + + /// Retired pointer + typedef cds::gc::details::retired_ptr retired_ptr; + + /// Array of retired pointers + /** + The vector of retired pointer ready to delete. + + The Hazard Pointer schema is build on thread-static arrays. For each HP-enabled thread the HP manager allocates + array of retired pointers. The array belongs to the thread: owner thread writes to the array, other threads + just read it. + */ + class retired_vector { + /// Underlying vector implementation + typedef cds::details::bounded_array retired_vector_impl; + + retired_vector_impl m_arr ; ///< the array of retired pointers + size_t m_nSize ; ///< Current size of \p m_arr + + public: + /// Iterator + typedef retired_vector_impl::iterator iterator; + + /// Constructor + retired_vector( const cds::gc::hp::GarbageCollector& HzpMgr ) CDS_NOEXCEPT; // inline + ~retired_vector() + {} + + /// Vector capacity. + /** + The capacity is constant for any thread. It is defined by cds::gc::hp::GarbageCollector. + */ + size_t capacity() const CDS_NOEXCEPT + { + return m_arr.capacity(); + } + + /// Current vector size (count of retired pointers in the vector) + size_t size() const CDS_NOEXCEPT + { + return m_nSize; + } + + /// Set vector size. Uses internally + void size( size_t nSize ) + { + assert( nSize <= capacity() ); + m_nSize = nSize; + } + + /// Pushes retired pointer to the vector + void push( const retired_ptr& p ) + { + assert( m_nSize < capacity() ); + m_arr[ m_nSize ] = p; + ++m_nSize; + } + + /// Checks if the vector is full (size() == capacity() ) + bool isFull() const CDS_NOEXCEPT + { + return m_nSize >= capacity(); + } + + /// Begin iterator + iterator begin() CDS_NOEXCEPT + { + return m_arr.begin(); + } + + /// End iterator + iterator end() CDS_NOEXCEPT + { + return m_arr.begin() + m_nSize ; + } + + /// Clears the vector. After clearing, size() == 0 + void clear() CDS_NOEXCEPT + { + m_nSize = 0; + } + }; + /// Hazard pointer record of the thread /** The structure of type "single writer - multiple reader": only the owner thread may write to this structure other threads have read-only access. */ - struct HPRec { - HPAllocator m_hzp ; ///< array of hazard pointers. Implicit \ref CDS_DEFAULT_ALLOCATOR dependency - retired_vector m_arrRetired ; ///< Retired pointer array + struct hp_record { + hp_allocator<> m_hzp; ///< array of hazard pointers. Implicit \ref CDS_DEFAULT_ALLOCATOR dependency + retired_vector m_arrRetired ; ///< Retired pointer array /// Ctor - HPRec( const cds::gc::hp::GarbageCollector& HzpMgr ); // inline - ~HPRec() + hp_record( const cds::gc::hp::GarbageCollector& HzpMgr ); // inline + ~hp_record() {} /// Clears all hazard pointers @@ -158,10 +244,10 @@ namespace cds { size_t nTotalRetiredPtrCount ; ///< Current total count of retired pointers size_t nRetiredPtrInFreeHPRecs ; ///< Count of retired pointer in free (unused) HP records - event_counter::value_type evcAllocHPRec ; ///< Count of HPRec allocations - event_counter::value_type evcRetireHPRec ; ///< Count of HPRec retire events - event_counter::value_type evcAllocNewHPRec; ///< Count of new HPRec allocations from heap - event_counter::value_type evcDeleteHPRec ; ///< Count of HPRec deletions + event_counter::value_type evcAllocHPRec ; ///< Count of \p hp_record allocations + event_counter::value_type evcRetireHPRec ; ///< Count of \p hp_record retire events + event_counter::value_type evcAllocNewHPRec; ///< Count of new \p hp_record allocations from heap + event_counter::value_type evcDeleteHPRec ; ///< Count of \p hp_record deletions event_counter::value_type evcScanCall ; ///< Count of Scan calling event_counter::value_type evcHelpScanCall ; ///< Count of HelpScan calling @@ -180,10 +266,10 @@ namespace cds { private: /// Internal GC statistics struct Statistics { - event_counter m_AllocHPRec ; ///< Count of HPRec allocations - event_counter m_RetireHPRec ; ///< Count of HPRec retire events - event_counter m_AllocNewHPRec ; ///< Count of new HPRec allocations from heap - event_counter m_DeleteHPRec ; ///< Count of HPRec deletions + event_counter m_AllocHPRec ; ///< Count of \p hp_record allocations + event_counter m_RetireHPRec ; ///< Count of \p hp_record retire events + event_counter m_AllocNewHPRec ; ///< Count of new \p hp_record allocations from heap + event_counter m_DeleteHPRec ; ///< Count of \p hp_record deletions event_counter m_ScanCallCount ; ///< Count of Scan calling event_counter m_HelpScanCallCount ; ///< Count of HelpScan calling @@ -193,8 +279,8 @@ namespace cds { event_counter m_DeferredNode ; ///< Count of objects that cannot be deleted in Scan phase because of a hazard_pointer guards it }; - /// Internal list of cds::gc::hp::details::HPRec - struct hplist_node: public details::HPRec + /// 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) @@ -202,7 +288,7 @@ namespace cds { //@cond hplist_node( const GarbageCollector& HzpMgr ) - : HPRec( HzpMgr ), + : hp_record( HzpMgr ), m_pNextNode( nullptr ), m_idOwner( OS::c_NullThreadId ), m_bFree( true ) @@ -305,19 +391,28 @@ namespace cds { } /// Checks if global GC object is constructed and may be used - static bool isUsed() + static bool isUsed() CDS_NOEXCEPT { return m_pHZPManager != nullptr; } /// Returns max Hazard Pointer count defined in construction time - size_t getHazardPointerCount() const { return m_nHazardPointerCount; } + size_t getHazardPointerCount() const CDS_NOEXCEPT + { + return m_nHazardPointerCount; + } /// Returns max thread count defined in construction time - size_t getMaxThreadCount() const { return m_nMaxThreadCount; } + size_t getMaxThreadCount() const CDS_NOEXCEPT + { + return m_nMaxThreadCount; + } /// Returns max size of retired objects array. It is defined in construction time - size_t getMaxRetiredPtrCount() const { return m_nMaxRetiredPtrCount; } + size_t getMaxRetiredPtrCount() const CDS_NOEXCEPT + { + return m_nMaxRetiredPtrCount; + } // Internal statistics @@ -365,10 +460,10 @@ namespace cds { public: // Internals for threads /// Allocates Hazard Pointer GC record. For internal use only - details::HPRec * AllocateHPRec(); + details::hp_record * AllocateHPRec(); /// Free HP record. For internal use only - void RetireHPRec( details::HPRec * pRec ); + void RetireHPRec( details::hp_record * pRec ); /// The main garbage collecting function /** @@ -381,7 +476,7 @@ namespace cds { Use \ref hzp_gc_setScanType "setScanType" member function to setup appropriate scan algorithm. */ - void Scan( details::HPRec * pRec ) + void Scan( details::hp_record * pRec ) { switch ( m_nScanType ) { case inplace: @@ -404,7 +499,7 @@ namespace cds { The function is called internally by Scan. */ - void HelpScan( details::HPRec * pThis ); + void HelpScan( details::hp_record * pThis ); protected: /// Classic scan algorithm @@ -431,14 +526,14 @@ namespace cds { This function is called internally by ThreadGC object when upper bound of thread's list of reclaimed pointers is reached. */ - void classic_scan( details::HPRec * pRec ); + void classic_scan( details::hp_record * pRec ); /// In-place scan algorithm /** @anchor hzp_gc_inplace_scan Unlike the \ref hzp_gc_classic_scan "classic_scan" algorithm, \p inplace_scan does not allocate any memory. All operations are performed in-place. */ - void inplace_scan( details::HPRec * pRec ); + void inplace_scan( details::hp_record * pRec ); }; /// Thread's hazard pointer manager @@ -450,8 +545,8 @@ namespace cds { */ class ThreadGC { - GarbageCollector& m_HzpManager ; ///< Hazard Pointer GC singleton - details::HPRec * m_pHzpRec ; ///< Pointer to thread's HZP record + GarbageCollector& m_HzpManager; ///< Hazard Pointer GC singleton + details::hp_record * m_pHzpRec; ///< Pointer to thread's HZP record public: /// Default constructor @@ -482,21 +577,21 @@ namespace cds { void fini() { if ( m_pHzpRec ) { - details::HPRec * pRec = m_pHzpRec; + details::hp_record * pRec = m_pHzpRec; m_pHzpRec = nullptr; m_HzpManager.RetireHPRec( pRec ); } } /// Initializes HP guard \p guard - details::HPGuard& allocGuard() + details::hp_guard& allocGuard() { assert( m_pHzpRec ); return m_pHzpRec->m_hzp.alloc(); } /// Frees HP guard \p guard - void freeGuard( details::HPGuard& guard ) + void freeGuard( details::hp_guard& guard ) { assert( m_pHzpRec ); m_pHzpRec->m_hzp.free( guard ); @@ -504,7 +599,7 @@ namespace cds { /// Initializes HP guard array \p arr template - void allocGuard( details::HPArray& arr ) + void allocGuard( details::hp_array& arr ) { assert( m_pHzpRec ); m_pHzpRec->m_hzp.alloc( arr ); @@ -512,7 +607,7 @@ namespace cds { /// Frees HP guard array \p arr template - void freeGuard( details::HPArray& arr ) + void freeGuard( details::hp_array& arr ) { assert( m_pHzpRec ); m_pHzpRec->m_hzp.free( arr ); @@ -545,7 +640,7 @@ namespace cds { //@endcond }; - /// Auto HPGuard. + /// Auto hp_guard. /** This class encapsulates Hazard Pointer guard to protect a pointer against deletion . It allocates one HP from thread's HP array in constructor and free the HP allocated in destruction time. @@ -553,12 +648,12 @@ namespace cds { class AutoHPGuard { //@cond - details::HPGuard& m_hp ; ///< Hazard pointer guarded + details::hp_guard& m_hp ; ///< Hazard pointer guarded ThreadGC& m_gc ; ///< Thread GC //@endcond public: - typedef details::HPGuard::hazard_ptr hazard_ptr ; ///< Hazard pointer type + typedef details::hp_guard::hazard_ptr hazard_ptr ; ///< Hazard pointer type public: /// Allocates HP guard from \p gc AutoHPGuard( ThreadGC& gc ) @@ -609,11 +704,11 @@ namespace cds { /// Auto-managed array of hazard pointers /** - This class is wrapper around cds::gc::hp::details::HPArray class. + This class is wrapper around cds::gc::hp::details::hp_array class. \p Count is the size of HP array */ template - class AutoHPArray: public details::HPArray + class AutoHPArray : public details::hp_array { ThreadGC& m_mgr ; ///< Thread GC diff --git a/projects/Win/vc12/cds.vcxproj b/projects/Win/vc12/cds.vcxproj index c78c9cc7..99b4958b 100644 --- a/projects/Win/vc12/cds.vcxproj +++ b/projects/Win/vc12/cds.vcxproj @@ -740,9 +740,7 @@ - - diff --git a/projects/Win/vc12/cds.vcxproj.filters b/projects/Win/vc12/cds.vcxproj.filters index 5ce38054..788c8b97 100644 --- a/projects/Win/vc12/cds.vcxproj.filters +++ b/projects/Win/vc12/cds.vcxproj.filters @@ -1157,15 +1157,9 @@ Header Files\cds\gc\hp - - Header Files\cds\gc\hp - Header Files\cds\gc\hp - - Header Files\cds\gc\hp - Header Files\cds\gc\hp diff --git a/src/hp_gc.cpp b/src/hp_gc.cpp index eb868c2a..a4681b99 100644 --- a/src/hp_gc.cpp +++ b/src/hp_gc.cpp @@ -103,7 +103,7 @@ namespace cds { namespace gc { p.free(); } - details::HPRec * GarbageCollector::AllocateHPRec() + details::hp_record * GarbageCollector::AllocateHPRec() { CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_AllocHPRec ); @@ -136,7 +136,7 @@ namespace cds { namespace gc { return hprec; } - void GarbageCollector::RetireHPRec( details::HPRec * pRec ) + void GarbageCollector::RetireHPRec( details::hp_record * pRec ) { assert( pRec != nullptr ); CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_RetireHPRec ); @@ -159,7 +159,7 @@ namespace cds { namespace gc { } } - void GarbageCollector::classic_scan( details::HPRec * pRec ) + void GarbageCollector::classic_scan( details::hp_record * pRec ) { CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_ScanCallCount ); @@ -205,7 +205,7 @@ namespace cds { namespace gc { } } - void GarbageCollector::inplace_scan( details::HPRec * pRec ) + void GarbageCollector::inplace_scan( details::hp_record * pRec ) { CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_ScanCallCount ); @@ -265,7 +265,7 @@ namespace cds { namespace gc { pRec->m_arrRetired.size( itInsert - itRetired ); } - void GarbageCollector::HelpScan( details::HPRec * pThis ) + void GarbageCollector::HelpScan( details::hp_record * pThis ) { CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_HelpScanCallCount ); @@ -294,7 +294,7 @@ namespace cds { namespace gc { } } - // We own the thread successfully. Now, we can see whether HPRec has retired pointers. + // We own the thread successfully. Now, we can see whether hp_record has retired pointers. // If it has ones then we move to pThis that is private for current thread. details::retired_vector& src = hprec->m_arrRetired; details::retired_vector& dest = pThis->m_arrRetired; diff --git a/tests/cppunit/test_main.cpp b/tests/cppunit/test_main.cpp index d9dfcc1b..f3c9814e 100644 --- a/tests/cppunit/test_main.cpp +++ b/tests/cppunit/test_main.cpp @@ -54,20 +54,20 @@ std::ostream& operator << (std::ostream& s, const cds::gc::hp::GarbageCollector::InternalState& stat) { s << "\nHZP GC internal state:" - << "\n\t\tHP record allocated=" << stat.nHPRecAllocated - << "\n\t\tHP records used=" << stat.nHPRecUsed - << "\n\t\tTotal retired ptr count=" << stat.nTotalRetiredPtrCount - << "\n\t\tRetired ptr in free HP records=" << stat.nRetiredPtrInFreeHPRecs + << "\n\t HP record allocated=" << stat.nHPRecAllocated + << "\n\t HP records used=" << stat.nHPRecUsed + << "\n\t Total retired ptr count=" << stat.nTotalRetiredPtrCount + << "\n\t Retired ptr in free HP records=" << stat.nRetiredPtrInFreeHPRecs << "\n\tEvents:" - << "\n\t\tHPRec allocations=" << stat.evcAllocHPRec - << "\n\t\tHPRec retire events=" << stat.evcRetireHPRec - << "\n\t\tnew HPRec allocations from heap=" << stat.evcAllocNewHPRec - << "\n\t\tHPRec deletions=" << stat.evcDeleteHPRec - << "\n\t\tScan calling=" << stat.evcScanCall - << "\n\t\tHelpScan calling=" << stat.evcHelpScanCall - << "\n\t\tScan calls from HelpScan=" << stat.evcScanFromHelpScan - << "\n\t\tretired objects deleting=" << stat.evcDeletedNode - << "\n\t\tguarded objects on Scan=" << stat.evcDeferredNode + << "\n\t HPRec allocations=" << stat.evcAllocHPRec + << "\n\t HPRec retire events=" << stat.evcRetireHPRec + << "\n\tnew HPRec allocations from heap=" << stat.evcAllocNewHPRec + << "\n\t HPRec deletions=" << stat.evcDeleteHPRec + << "\n\t Scan call count=" << stat.evcScanCall + << "\n\t HelpScan call count=" << stat.evcHelpScanCall + << "\n\t Scan calls from HelpScan=" << stat.evcScanFromHelpScan + << "\n\t retired object deleting=" << stat.evcDeletedNode + << "\n\t guarded object on Scan=" << stat.evcDeferredNode << std::endl; return s;