From 9b4289e2ef6efad125925b14ae6cdcc670ce4d67 Mon Sep 17 00:00:00 2001 From: khizmax Date: Sat, 15 Nov 2014 16:32:40 +0300 Subject: [PATCH] Hazard Pointer GC refactoring --- cds/gc/{hp => details}/hp.h | 56 +++++++++++++++++---------- cds/gc/{hp => }/details/hp_alloc.h | 12 +++--- cds/gc/{hp => }/details/hp_inline.h | 6 +-- cds/gc/{hp => }/details/hp_type.h | 6 +-- cds/gc/hp/hp_decl.h | 14 +++---- projects/Win/vc12/cds.vcxproj | 7 ++-- projects/Win/vc12/cds.vcxproj.filters | 21 +++++----- src/hp_gc.cpp | 8 ++-- 8 files changed, 75 insertions(+), 55 deletions(-) rename cds/gc/{hp => details}/hp.h (95%) rename cds/gc/{hp => }/details/hp_alloc.h (97%) rename cds/gc/{hp => }/details/hp_inline.h (85%) rename cds/gc/{hp => }/details/hp_type.h (77%) diff --git a/cds/gc/hp/hp.h b/cds/gc/details/hp.h similarity index 95% rename from cds/gc/hp/hp.h rename to cds/gc/details/hp.h index 9124850a..0e9f0c0d 100644 --- a/cds/gc/hp/hp.h +++ b/cds/gc/details/hp.h @@ -1,14 +1,14 @@ //$$CDS-header$$ -#ifndef __CDS_GC_HP_HP_H -#define __CDS_GC_HP_HP_H +#ifndef __CDS_GC_DETAILS_HP_H +#define __CDS_GC_DETAILS_HP_H #include #include #include -#include -#include +#include +#include #if CDS_COMPILER == CDS_COMPILER_MSVC # pragma warning(push) @@ -460,10 +460,10 @@ namespace cds { public: // Internals for threads /// Allocates Hazard Pointer GC record. For internal use only - details::hp_record * AllocateHPRec(); + details::hp_record * alloc_hp_record(); /// Free HP record. For internal use only - void RetireHPRec( details::hp_record * pRec ); + void free_hp_record( details::hp_record * pRec ); /// The main garbage collecting function /** @@ -570,7 +570,7 @@ namespace cds { void init() { if ( !m_pHzpRec ) - m_pHzpRec = m_HzpManager.AllocateHPRec(); + m_pHzpRec = m_HzpManager.alloc_hp_record(); } /// Finalization. Repeat call is available @@ -579,7 +579,7 @@ namespace cds { if ( m_pHzpRec ) { details::hp_record * pRec = m_pHzpRec; m_pHzpRec = nullptr; - m_HzpManager.RetireHPRec( pRec ); + m_HzpManager.free_hp_record( pRec ); } } @@ -617,11 +617,26 @@ namespace cds { template void retirePtr( T * p, void (* pFunc)(T *) ) { + /* + union { + T * p; + hazard_pointer hp; + } cast_ptr; + cast_ptr.p = p; + + uinion{ + void( *pFunc )(T *); + free_retired_ptr_func hpFunc; + } cast_func; + cast_func.pFunc = pFunc; + + retirePtr( details::retired_ptr( cast_ptr.hp, cast_func.hpFunc ) ); + */ retirePtr( details::retired_ptr( reinterpret_cast( p ), reinterpret_cast( pFunc ) ) ); } /// Places retired pointer \p into thread's array of retired pointer for deferred reclamation - void retirePtr( const details::retired_ptr& p ) + void retirePtr( details::retired_ptr const& p ) { m_pHzpRec->m_arrRetired.push( p ); @@ -643,9 +658,10 @@ namespace cds { /// 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. + It allocates one HP from thread's HP array in constructor and free the hazard pointer allocated + in destructor. */ - class AutoHPGuard + class guard { //@cond details::hp_guard& m_hp ; ///< Hazard pointer guarded @@ -656,14 +672,14 @@ namespace cds { typedef details::hp_guard::hazard_ptr hazard_ptr ; ///< Hazard pointer type public: /// Allocates HP guard from \p gc - AutoHPGuard( ThreadGC& gc ) + guard( ThreadGC& gc ) : m_hp( gc.allocGuard() ) , m_gc( gc ) {} /// Allocates HP guard from \p gc and protects the pointer \p p of type \p T template - AutoHPGuard( ThreadGC& gc, T * p ) + guard( ThreadGC& gc, T * p ) : m_hp( gc.allocGuard() ) , m_gc( gc ) { @@ -671,7 +687,7 @@ namespace cds { } /// Frees HP guard. The pointer guarded may be deleted after this. - ~AutoHPGuard() + ~guard() { m_gc.freeGuard( m_hp ); } @@ -708,7 +724,7 @@ namespace cds { \p Count is the size of HP array */ template - class AutoHPArray : public details::hp_array + class array : public details::hp_array { ThreadGC& m_mgr ; ///< Thread GC @@ -716,19 +732,19 @@ namespace cds { /// Rebind array for other size \p COUNT2 template struct rebind { - typedef AutoHPArray other ; ///< rebinding result + typedef array other; ///< rebinding result }; public: /// Allocates array of HP guard from \p mgr - AutoHPArray( ThreadGC& mgr ) + array( ThreadGC& mgr ) : m_mgr( mgr ) { mgr.allocGuard( *this ); } /// Frees array of HP guard - ~AutoHPArray() + ~array() { m_mgr.freeGuard( *this ); } @@ -741,10 +757,10 @@ namespace cds { }} // namespace cds::gc // Inlines -#include +#include #if CDS_COMPILER == CDS_COMPILER_MSVC # pragma warning(pop) #endif -#endif // #ifndef __CDS_GC_HP_HP_H +#endif // #ifndef __CDS_GC_DETAILS_HP_H diff --git a/cds/gc/hp/details/hp_alloc.h b/cds/gc/details/hp_alloc.h similarity index 97% rename from cds/gc/hp/details/hp_alloc.h rename to cds/gc/details/hp_alloc.h index 05cc6260..e057e1ba 100644 --- a/cds/gc/hp/details/hp_alloc.h +++ b/cds/gc/details/hp_alloc.h @@ -1,11 +1,11 @@ //$$CDS-header$$ -#ifndef __CDS_GC_HP_DETAILS_HP_ALLOC_H -#define __CDS_GC_HP_DETAILS_HP_ALLOC_H +#ifndef __CDS_GC_DETAILS_HP_ALLOC_H +#define __CDS_GC_DETAILS_HP_ALLOC_H #include #include -#include +#include //@cond namespace cds { @@ -20,7 +20,7 @@ namespace cds { /// Hazard pointer guard /** It is unsafe to use this class directly. - Instead, the AutoHPGuard class should be used. + Instead, the \p hp::guard class should be used. */ class hp_guard : protected atomics::atomic < hazard_pointer > { @@ -104,7 +104,7 @@ namespace cds { Template parameter \p Count defines the size of hazard pointer array. \p Count parameter should not exceed GarbageCollector::getHazardPointerCount(). - It is unsafe to use this class directly. Instead, the AutoHPArray should be used. + It is unsafe to use this class directly. Instead, the \p hp::array should be used. 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 @@ -317,4 +317,4 @@ namespace cds { } // namespace cds //@endcond -#endif // #ifndef __CDS_GC_HP_DETAILS_HP_ALLOC_H +#endif // #ifndef __CDS_GC_DETAILS_HP_ALLOC_H diff --git a/cds/gc/hp/details/hp_inline.h b/cds/gc/details/hp_inline.h similarity index 85% rename from cds/gc/hp/details/hp_inline.h rename to cds/gc/details/hp_inline.h index 7142b780..86bc997c 100644 --- a/cds/gc/hp/details/hp_inline.h +++ b/cds/gc/details/hp_inline.h @@ -1,7 +1,7 @@ //$$CDS-header$$ -#ifndef __CDS_GC_HP_DETAILS_HP_INLINE_H -#define __CDS_GC_HP_DETAILS_HP_INLINE_H +#ifndef __CDS_GC_DETAILS_HP_INLINE_H +#define __CDS_GC_DETAILS_HP_INLINE_H namespace cds { namespace gc{ namespace hp { namespace details { @@ -23,4 +23,4 @@ namespace cds { } // namespace cds -#endif // #ifndef __CDS_GC_HP_DETAILS_HP_INLINE_H +#endif // #ifndef __CDS_GC_DETAILS_HP_INLINE_H diff --git a/cds/gc/hp/details/hp_type.h b/cds/gc/details/hp_type.h similarity index 77% rename from cds/gc/hp/details/hp_type.h rename to cds/gc/details/hp_type.h index 2f22ebd4..21671216 100644 --- a/cds/gc/hp/details/hp_type.h +++ b/cds/gc/details/hp_type.h @@ -1,7 +1,7 @@ //$$CDS-header$$ -#ifndef __CDS_GC_HP_DETAILS_HP_TYPE_H -#define __CDS_GC_HP_DETAILS_HP_TYPE_H +#ifndef __CDS_GC_DETAILS_HP_TYPE_H +#define __CDS_GC_DETAILS_HP_TYPE_H #include // free_retired_ptr_func @@ -18,6 +18,6 @@ namespace cds { } } -#endif // #ifndef __CDS_GC_HP_DETAILS_HP_TYPE_H +#endif // #ifndef __CDS_GC_DETAILS_HP_TYPE_H diff --git a/cds/gc/hp/hp_decl.h b/cds/gc/hp/hp_decl.h index 44ef1d39..9de3da4e 100644 --- a/cds/gc/hp/hp_decl.h +++ b/cds/gc/hp/hp_decl.h @@ -4,7 +4,7 @@ #define __CDS_GC_HP_HP_DECL_H #include // overflow_error -#include +#include #include namespace cds { namespace gc { @@ -86,12 +86,12 @@ namespace cds { namespace gc { /// Hazard Pointer guard /** @headerfile cds/gc/hp.h - This class is a wrapper for hp::AutoHPGuard. + This class is a wrapper for \p hp::guard. */ - class Guard : public hp::AutoHPGuard + class Guard : public hp::guard { //@cond - typedef hp::AutoHPGuard base_class; + typedef hp::guard base_class; //@endcond public: @@ -206,14 +206,14 @@ namespace cds { namespace gc { /// Array of Hazard Pointer guards /** @headerfile cds/gc/hp.h - This class is a wrapper for hp::AutoHPArray template. + This class is a wrapper for \p hp::array template. Template parameter \p Count defines the size of HP array. */ template - class GuardArray : public hp::AutoHPArray + class GuardArray : public hp::array { //@cond - typedef hp::AutoHPArray base_class; + typedef hp::array base_class; //@endcond public: /// Rebind array for other size \p Count2 diff --git a/projects/Win/vc12/cds.vcxproj b/projects/Win/vc12/cds.vcxproj index 99b4958b..3b31649a 100644 --- a/projects/Win/vc12/cds.vcxproj +++ b/projects/Win/vc12/cds.vcxproj @@ -734,14 +734,15 @@ + + + + - - - diff --git a/projects/Win/vc12/cds.vcxproj.filters b/projects/Win/vc12/cds.vcxproj.filters index 788c8b97..d8599743 100644 --- a/projects/Win/vc12/cds.vcxproj.filters +++ b/projects/Win/vc12/cds.vcxproj.filters @@ -1154,15 +1154,6 @@ Header Files\cds\gc - - Header Files\cds\gc\hp - - - Header Files\cds\gc\hp - - - Header Files\cds\gc\hp - Header Files\cds\gc\hp @@ -1184,5 +1175,17 @@ Source Files + + Header Files\cds\gc\details + + + Header Files\cds\gc\details + + + Header Files\cds\gc\details + + + Header Files\cds\gc\details + \ No newline at end of file diff --git a/src/hp_gc.cpp b/src/hp_gc.cpp index a4681b99..4899dd4d 100644 --- a/src/hp_gc.cpp +++ b/src/hp_gc.cpp @@ -9,7 +9,7 @@ 2008.02.10 Maxim.Khiszinsky Created */ -#include +#include #include // std::sort #include "hp_const.h" @@ -103,7 +103,7 @@ namespace cds { namespace gc { p.free(); } - details::hp_record * GarbageCollector::AllocateHPRec() + details::hp_record * GarbageCollector::alloc_hp_record() { CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_AllocHPRec ); @@ -136,7 +136,7 @@ namespace cds { namespace gc { return hprec; } - void GarbageCollector::RetireHPRec( details::hp_record * pRec ) + void GarbageCollector::free_hp_record( details::hp_record * pRec ) { assert( pRec != nullptr ); CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_RetireHPRec ); @@ -154,7 +154,7 @@ namespace cds { namespace gc { for ( hplist_node * hprec = m_pListHead.load(atomics::memory_order_acquire); hprec; hprec = pNext ) { pNext = hprec->m_pNextNode; if ( hprec->m_idOwner.load(atomics::memory_order_relaxed) != nullThreadId ) { - RetireHPRec( hprec ); + free_hp_record( hprec ); } } } -- 2.34.1