From ef671b8b2db9357d83de1a0fae3044f1d2b9d6f7 Mon Sep 17 00:00:00 2001 From: khizmax Date: Sat, 15 Nov 2014 18:08:49 +0300 Subject: [PATCH] rearrange cds/gc directory --- cds/gc/dhp.h | 4 +- cds/gc/hp.h | 4 +- cds/gc/{dhp => impl}/dhp_decl.h | 123 +++++++++++++++++--------- cds/gc/{dhp => impl}/dhp_impl.h | 4 +- cds/gc/{hp => impl}/hp_decl.h | 79 +++++++++++------ cds/gc/{hp => impl}/hp_impl.h | 4 +- cds/threading/details/_common.h | 4 +- projects/Win/vc12/cds.vcxproj | 9 +- projects/Win/vc12/cds.vcxproj.filters | 34 +++---- 9 files changed, 161 insertions(+), 104 deletions(-) rename cds/gc/{dhp => impl}/dhp_decl.h (74%) rename cds/gc/{dhp => impl}/dhp_impl.h (89%) rename cds/gc/{hp => impl}/hp_decl.h (87%) rename cds/gc/{hp => impl}/hp_impl.h (92%) diff --git a/cds/gc/dhp.h b/cds/gc/dhp.h index 6209e815..35f7d871 100644 --- a/cds/gc/dhp.h +++ b/cds/gc/dhp.h @@ -3,8 +3,8 @@ #ifndef __CDS_GC_DHP_H #define __CDS_GC_DHP_H -#include -#include +#include +#include #include #endif // #ifndef __CDS_GC_DHP_H diff --git a/cds/gc/hp.h b/cds/gc/hp.h index 54618eab..eea63e4e 100644 --- a/cds/gc/hp.h +++ b/cds/gc/hp.h @@ -3,8 +3,8 @@ #ifndef __CDS_GC_HP_H #define __CDS_GC_HP_H -#include -#include +#include +#include #include #endif // #ifndef __CDS_GC_HP_H diff --git a/cds/gc/dhp/dhp_decl.h b/cds/gc/impl/dhp_decl.h similarity index 74% rename from cds/gc/dhp/dhp_decl.h rename to cds/gc/impl/dhp_decl.h index 05e5f058..9c26fd87 100644 --- a/cds/gc/dhp/dhp_decl.h +++ b/cds/gc/impl/dhp_decl.h @@ -12,14 +12,26 @@ namespace cds { namespace gc { /// Dynamic Hazard Pointer garbage collector /** @ingroup cds_garbage_collector @headerfile cds/gc/dhp.h - This class is a wrapper for Dynamic Hazard Pointer garbage collector internal implementation. - See \ref cds_how_to_use "How to use" section for details of garbage collector applying. + Implementation of Dynamic Hazard Pointer garbage collector. + + Sources: + - [2002] Maged M.Michael "Safe memory reclamation for dynamic lock-freeobjects using atomic reads and writes" + - [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" + + Dynamic Hazard Pointers SMR (safe memory reclamation) provides an unbounded number of hazard pointer per thread + despite of classic Hazard Pointer SMR in which the count of the hazard pointef per thread is limited. + + See \ref cds_how_to_use "How to use" section for details how to apply garbage collector. */ class DHP { public: /// Native guarded pointer type + /** + @headerfile cds/gc/dhp.h + */ typedef void * guarded_pointer; /// Atomic reference @@ -41,9 +53,12 @@ namespace cds { namespace gc { template using atomic_marked_ptr = atomics::atomic; /// Thread GC implementation for internal usage + /** + @headerfile cds/gc/dhp.h + */ typedef dhp::ThreadGC thread_gc_impl; - /// Wrapper for dhp::ThreadGC class + /// Thread-level garbage collector /** @headerfile cds/gc/dhp.h This class performs automatically attaching/detaching Dynamic Hazard Pointer GC @@ -79,7 +94,12 @@ namespace cds { namespace gc { /// Dynamic Hazard Pointer guard /** @headerfile cds/gc/dhp.h - This class is a wrapper for dhp::Guard. + + A guard is the hazard pointer. + Additionally, the \p %Guard class manages allocation and deallocation of the hazard pointer + + A \p %Guard object is not copy- and move-constructible + and not copy- and move-assignable. */ class Guard: public dhp::Guard { @@ -88,8 +108,14 @@ namespace cds { namespace gc { //@endcond public: + // Default ctor + Guard() CDS_NOEXCEPT; // inline in dhp_impl.h + //@cond - Guard() ; // inline in dhp_impl.h + Guard( Guard const& ) = delete; + Guard( Guard&& s ) = delete; + Guard& operator=(Guard const&) = delete; + Guard& operator=(Guard&&) = delete; //@endcond /// Protects a pointer of type atomic @@ -100,7 +126,7 @@ namespace cds { namespace gc { to the HP slot repeatedly until the guard's value equals \p toGuard */ template - T protect( atomics::atomic const& toGuard ) + T protect( atomics::atomic const& toGuard ) CDS_NOEXCEPT { T pCur = toGuard.load(atomics::memory_order_relaxed); T pRet; @@ -129,7 +155,7 @@ namespace cds { namespace gc { Really, the result of f( toGuard.load() ) is assigned to the hazard pointer. */ template - T protect( atomics::atomic const& toGuard, Func f ) + T protect( atomics::atomic const& toGuard, Func f ) CDS_NOEXCEPT_( f( toGuard.load( atomics::memory_order_relaxed ))) { T pCur = toGuard.load(atomics::memory_order_relaxed); T pRet; @@ -143,17 +169,18 @@ namespace cds { namespace gc { /// Store \p p to the guard /** - The function equals to a simple assignment, no loop is performed. - Can be used for a pointer that cannot be changed concurrently. + The function is just an assignment, no loop is performed. + Can be used for a pointer that cannot be changed concurrently + or for already guarded pointer. */ template - T * assign( T * p ) + T * assign( T * p ) CDS_NOEXCEPT { return base_class::operator =(p); } //@cond - std::nullptr_t assign( std::nullptr_t ) + std::nullptr_t assign( std::nullptr_t ) CDS_NOEXCEPT { return base_class::operator =(nullptr); } @@ -161,47 +188,50 @@ namespace cds { namespace gc { /// Store marked pointer \p p to the guard /** - The function equals to a simple assignment of p.ptr(), no loop is performed. - Can be used for a marked pointer that cannot be changed concurrently. + The function is just an assignment of p.ptr(), no loop is performed. + Can be used for a marked pointer that cannot be changed concurrently + or for already guarded pointer. */ template - T * assign( cds::details::marked_ptr p ) + T * assign( cds::details::marked_ptr p ) CDS_NOEXCEPT { return base_class::operator =( p.ptr() ); } /// Copy from \p src guard to \p this guard - void copy( Guard const& src ) + void copy( Guard const& src ) CDS_NOEXCEPT { assign( src.get_native() ); } - /// Clear value of the guard - void clear() + /// Clears value of the guard + void clear() CDS_NOEXCEPT { base_class::clear(); } - /// Get the value currently protected (relaxed read) + /// Gets the value currently protected (relaxed read) template - T * get() const + T * get() const CDS_NOEXCEPT { return reinterpret_cast( get_native() ); } - /// Get native guarded pointer stored - guarded_pointer get_native() const + /// Gets native guarded pointer stored + guarded_pointer get_native() const CDS_NOEXCEPT { return base_class::get_guard()->pPost.load(atomics::memory_order_relaxed); } - }; /// Array of Dynamic Hazard Pointer guards /** @headerfile cds/gc/dhp.h - This class is a wrapper for dhp::GuardArray template. - Template parameter \p Count defines the size of DHP array. + The class is intended for allocating an array of hazard pointer guards. + Template parameter \p Count defines the size of the array. + + A \p %GuardArray object is not copy- and move-constructible + and not copy- and move-assignable. */ template class GuardArray: public dhp::GuardArray @@ -210,15 +240,21 @@ namespace cds { namespace gc { typedef dhp::GuardArray base_class; //@endcond public: - /// Rebind array for other size \p COUNT2 + /// Rebind array for other size \p OtherCount template struct rebind { typedef GuardArray other ; ///< rebinding result }; public: + // Default ctor + GuardArray() CDS_NOEXCEPT; // inline in dhp_impl.h + //@cond - GuardArray() ; // inline in dhp_impl.h + GuardArray( GuardArray const& ) = delete; + GuardArray( GuardArray&& ) = delete; + GuardArray& operator=(GuardArray const&) = delete; + GuardArray& operator-(GuardArray&&) = delete; //@endcond /// Protects a pointer of type \p atomic @@ -229,7 +265,7 @@ namespace cds { namespace gc { to the slot \p nIndex repeatedly until the guard's value equals \p toGuard */ template - T protect(size_t nIndex, atomics::atomic const& toGuard ) + T protect( size_t nIndex, atomics::atomic const& toGuard ) CDS_NOEXCEPT { T pRet; do { @@ -248,16 +284,16 @@ namespace cds { namespace gc { The function is useful for intrusive containers when \p toGuard is a node pointer that should be converted to a pointer to the value type before guarding. - The parameter \p f of type Func is a functor that makes this conversion: + The parameter \p f of type Func is a functor to make that conversion: \code struct functor { value_type * operator()( T * p ); }; \endcode - Really, the result of f( toGuard.load() ) is assigned to the hazard pointer. + Actually, the result of f( toGuard.load() ) is assigned to the hazard pointer. */ template - T protect(size_t nIndex, atomics::atomic const& toGuard, Func f ) + T protect( size_t nIndex, atomics::atomic const& toGuard, Func f ) CDS_NOEXCEPT_( f( toGuard.load( atomics::memory_order_relaxed ))) { T pRet; do { @@ -267,12 +303,12 @@ namespace cds { namespace gc { return pRet; } - /// Store \p to the slot \p nIndex + /// Store \p p to the slot \p nIndex /** - The function equals to a simple assignment, no loop is performed. + The function is just an assignment, no loop is performed. */ template - T * assign( size_t nIndex, T * p ) + T * assign( size_t nIndex, T * p ) CDS_NOEXCEPT { base_class::set(nIndex, p); return p; @@ -280,48 +316,49 @@ namespace cds { namespace gc { /// Store marked pointer \p p to the guard /** - The function equals to a simple assignment of p.ptr(), no loop is performed. - Can be used for a marked pointer that cannot be changed concurrently. + The function is just an assignment of p.ptr(), no loop is performed. + Can be used for a marked pointer that cannot be changed concurrently + or for already guarded pointer. */ template - T * assign( size_t nIndex, cds::details::marked_ptr p ) + T * assign( size_t nIndex, cds::details::marked_ptr p ) CDS_NOEXCEPT { return assign( nIndex, p.ptr() ); } /// Copy guarded value from \p src guard to slot at index \p nIndex - void copy( size_t nIndex, Guard const& src ) + void copy( size_t nIndex, Guard const& src ) CDS_NOEXCEPT { assign( nIndex, src.get_native() ); } /// Copy guarded value from slot \p nSrcIndex to slot at index \p nDestIndex - void copy( size_t nDestIndex, size_t nSrcIndex ) + void copy( size_t nDestIndex, size_t nSrcIndex ) CDS_NOEXCEPT { assign( nDestIndex, get_native( nSrcIndex )); } /// Clear value of the slot \p nIndex - void clear( size_t nIndex) + void clear( size_t nIndex ) CDS_NOEXCEPT { base_class::clear( nIndex ); } /// Get current value of slot \p nIndex template - T * get( size_t nIndex) const + T * get( size_t nIndex ) const CDS_NOEXCEPT { return reinterpret_cast( get_native( nIndex ) ); } /// Get native guarded pointer stored - guarded_pointer get_native( size_t nIndex ) const + guarded_pointer get_native( size_t nIndex ) const CDS_NOEXCEPT { return base_class::operator[](nIndex).get_guard()->pPost.load(atomics::memory_order_relaxed); } /// Capacity of the guard array - static CDS_CONSTEXPR size_t capacity() + static CDS_CONSTEXPR size_t capacity() CDS_NOEXCEPT { return Count; } @@ -358,7 +395,7 @@ namespace cds { namespace gc { The function always returns \p true since the guard count is unlimited for DHP garbage collector. */ - static bool check_available_guards( size_t nCountNeeded, bool /*bRaiseException*/ = true ) + static CDS_CONSTEXPR bool check_available_guards( size_t nCountNeeded, bool /*bRaiseException*/ = true ) { CDS_UNUSED( nCountNeeded ); return true; diff --git a/cds/gc/dhp/dhp_impl.h b/cds/gc/impl/dhp_impl.h similarity index 89% rename from cds/gc/dhp/dhp_impl.h rename to cds/gc/impl/dhp_impl.h index a21db87a..10b15f8e 100644 --- a/cds/gc/dhp/dhp_impl.h +++ b/cds/gc/impl/dhp_impl.h @@ -23,12 +23,12 @@ namespace cds { namespace gc { cds::threading::Manager::detachThread(); } - inline DHP::Guard::Guard() + inline DHP::Guard::Guard() CDS_NOEXCEPT : Guard::base_class( cds::threading::getGC() ) {} template - inline DHP::GuardArray::GuardArray() + inline DHP::GuardArray::GuardArray() CDS_NOEXCEPT : GuardArray::base_class( cds::threading::getGC() ) {} diff --git a/cds/gc/hp/hp_decl.h b/cds/gc/impl/hp_decl.h similarity index 87% rename from cds/gc/hp/hp_decl.h rename to cds/gc/impl/hp_decl.h index 9de3da4e..2beb88af 100644 --- a/cds/gc/hp/hp_decl.h +++ b/cds/gc/impl/hp_decl.h @@ -14,19 +14,22 @@ namespace cds { namespace gc { /** @ingroup cds_garbage_collector @headerfile cds/gc/hp.h - This class realizes a wrapper for Hazard Pointer garbage collector internal implementation. + Implementation of classic Hazard Pointer garbage collector. Sources: - [2002] Maged M.Michael "Safe memory reclamation for dynamic lock-freeobjects using atomic reads and writes" - [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" - See \ref cds_how_to_use "How to use" section for details of garbage collector applying. + See \ref cds_how_to_use "How to use" section for details how to apply garbage collector. */ class HP { public: /// Native guarded pointer type + /** + @headerfile cds/gc/hp.h + */ typedef gc::hp::hazard_pointer guarded_pointer; /// Atomic reference @@ -48,6 +51,9 @@ namespace cds { namespace gc { template using atomic_type = atomics::atomic; /// Thread GC implementation for internal usage + /** + @headerfile cds/gc/hp.h + */ typedef hp::ThreadGC thread_gc_impl; /// Wrapper for hp::ThreadGC class @@ -86,7 +92,12 @@ namespace cds { namespace gc { /// Hazard Pointer guard /** @headerfile cds/gc/hp.h - This class is a wrapper for \p hp::guard. + + A guard is the hazard pointer. + Additionally, the \p %Guard class manages allocation and deallocation of the hazard pointer + + A \p %Guard object is not copy- and move-constructible + and not copy- and move-assignable. */ class Guard : public hp::guard { @@ -95,8 +106,14 @@ namespace cds { namespace gc { //@endcond public: + /// Default ctor + Guard() CDS_NOEXCEPT; // inline in hp_impl.h + //@cond - Guard() ; // inline in hp_impl.h + Guard( Guard const& ) = delete; + Guard( Guard&& s ) = delete; + Guard& operator=(Guard const&) = delete; + Guard& operator=(Guard&&) = delete; //@endcond /// Protects a pointer of type \p atomic @@ -107,7 +124,7 @@ namespace cds { namespace gc { to the HP slot repeatedly until the guard's value equals \p toGuard */ template - T protect( atomics::atomic const& toGuard ) + T protect( atomics::atomic const& toGuard ) CDS_NOEXCEPT { T pCur = toGuard.load(atomics::memory_order_relaxed); T pRet; @@ -136,7 +153,7 @@ namespace cds { namespace gc { Really, the result of f( toGuard.load() ) is assigned to the hazard pointer. */ template - T protect( atomics::atomic const& toGuard, Func f ) + T protect( atomics::atomic const& toGuard, Func f ) CDS_NOEXCEPT_( f( toGuard.load( atomics::memory_order_relaxed ) ) ) { T pCur = toGuard.load(atomics::memory_order_relaxed); T pRet; @@ -154,20 +171,20 @@ namespace cds { namespace gc { Can be used for a pointer that cannot be changed concurrently */ template - T * assign( T * p ) + T * assign( T * p ) CDS_NOEXCEPT { return base_class::operator =(p); } //@cond - std::nullptr_t assign( std::nullptr_t ) + std::nullptr_t assign( std::nullptr_t ) CDS_NOEXCEPT { return base_class::operator =(nullptr); } //@endcond /// Copy from \p src guard to \p this guard - void copy( Guard const& src ) + void copy( Guard const& src ) CDS_NOEXCEPT { assign( src.get_native() ); } @@ -178,26 +195,26 @@ namespace cds { namespace gc { Can be used for a marked pointer that cannot be changed concurrently. */ template - T * assign( cds::details::marked_ptr p ) + T * assign( cds::details::marked_ptr p ) CDS_NOEXCEPT { return base_class::operator =( p.ptr() ); } /// Clear value of the guard - void clear() + void clear() CDS_NOEXCEPT { assign( nullptr ); } /// Get the value currently protected template - T * get() const + T * get() const CDS_NOEXCEPT { return reinterpret_cast( get_native() ); } /// Get native hazard pointer stored - guarded_pointer get_native() const + guarded_pointer get_native() const CDS_NOEXCEPT { return base_class::get(); } @@ -206,8 +223,11 @@ namespace cds { namespace gc { /// Array of Hazard Pointer guards /** @headerfile cds/gc/hp.h - This class is a wrapper for \p hp::array template. - Template parameter \p Count defines the size of HP array. + The class is intended for allocating an array of hazard pointer guards. + Template parameter \p Count defines the size of the array. + + A \p %GuardArray object is not copy- and move-constructible + and not copy- and move-assignable. */ template class GuardArray : public hp::array @@ -223,9 +243,16 @@ namespace cds { namespace gc { }; public: + /// Default ctor + GuardArray() CDS_NOEXCEPT; // inline in hp_impl.h + //@cond - GuardArray() ; // inline in hp_impl.h + GuardArray( GuardArray const& ) = delete; + GuardArray( GuardArray&& ) = delete; + GuardArray& operator=(GuardArray const&) = delete; + GuardArray& operator-(GuardArray&&) = delete; //@endcond + /// Protects a pointer of type \p atomic /** Return the value of \p toGuard @@ -234,7 +261,7 @@ namespace cds { namespace gc { to the slot \p nIndex repeatedly until the guard's value equals \p toGuard */ template - T protect(size_t nIndex, atomics::atomic const& toGuard ) + T protect( size_t nIndex, atomics::atomic const& toGuard ) CDS_NOEXCEPT { T pRet; do { @@ -262,7 +289,7 @@ namespace cds { namespace gc { Really, the result of f( toGuard.load() ) is assigned to the hazard pointer. */ template - T protect(size_t nIndex, atomics::atomic const& toGuard, Func f ) + T protect( size_t nIndex, atomics::atomic const& toGuard, Func f ) CDS_NOEXCEPT_( f( toGuard.load( atomics::memory_order_acquire ))) { T pRet; do { @@ -277,7 +304,7 @@ namespace cds { namespace gc { The function equals to a simple assignment, no loop is performed. */ template - T * assign( size_t nIndex, T * p ) + T * assign( size_t nIndex, T * p ) CDS_NOEXCEPT { base_class::set(nIndex, p); return p; @@ -289,44 +316,44 @@ namespace cds { namespace gc { Can be used for a marked pointer that cannot be changed concurrently. */ template - T * assign( size_t nIndex, cds::details::marked_ptr p ) + T * assign( size_t nIndex, cds::details::marked_ptr p ) CDS_NOEXCEPT { return assign( nIndex, p.ptr() ); } /// Copy guarded value from \p src guard to slot at index \p nIndex - void copy( size_t nIndex, Guard const& src ) + void copy( size_t nIndex, Guard const& src ) CDS_NOEXCEPT { assign( nIndex, src.get_native() ); } /// Copy guarded value from slot \p nSrcIndex to slot at index \p nDestIndex - void copy( size_t nDestIndex, size_t nSrcIndex ) + void copy( size_t nDestIndex, size_t nSrcIndex ) CDS_NOEXCEPT { assign( nDestIndex, get_native( nSrcIndex )); } /// Clear value of the slot \p nIndex - void clear( size_t nIndex) + void clear( size_t nIndex ) CDS_NOEXCEPT { base_class::clear( nIndex ); } /// Get current value of slot \p nIndex template - T * get( size_t nIndex) const + T * get( size_t nIndex ) const CDS_NOEXCEPT { return reinterpret_cast( get_native( nIndex ) ); } /// Get native hazard pointer stored - guarded_pointer get_native( size_t nIndex ) const + guarded_pointer get_native( size_t nIndex ) const CDS_NOEXCEPT { return base_class::operator[](nIndex).get(); } /// Capacity of the guard array - static CDS_CONSTEXPR size_t capacity() + static CDS_CONSTEXPR size_t capacity() CDS_NOEXCEPT { return Count; } diff --git a/cds/gc/hp/hp_impl.h b/cds/gc/impl/hp_impl.h similarity index 92% rename from cds/gc/hp/hp_impl.h rename to cds/gc/impl/hp_impl.h index b78e1607..8d046e30 100644 --- a/cds/gc/hp/hp_impl.h +++ b/cds/gc/impl/hp_impl.h @@ -24,12 +24,12 @@ namespace cds { namespace gc { cds::threading::Manager::detachThread(); } - inline HP::Guard::Guard() + inline HP::Guard::Guard() CDS_CONSTEXPR : Guard::base_class( cds::threading::getGC() ) {} template - inline HP::GuardArray::GuardArray() + inline HP::GuardArray::GuardArray() CDS_CONSTEXPR : GuardArray::base_class( cds::threading::getGC() ) {} diff --git a/cds/threading/details/_common.h b/cds/threading/details/_common.h index 1079303f..73db0ec4 100644 --- a/cds/threading/details/_common.h +++ b/cds/threading/details/_common.h @@ -3,8 +3,8 @@ #ifndef __CDS_THREADING__COMMON_H #define __CDS_THREADING__COMMON_H -#include -#include +#include +#include #include #include diff --git a/projects/Win/vc12/cds.vcxproj b/projects/Win/vc12/cds.vcxproj index 044f1fe9..b6db0612 100644 --- a/projects/Win/vc12/cds.vcxproj +++ b/projects/Win/vc12/cds.vcxproj @@ -740,12 +740,11 @@ - - - - - + + + + diff --git a/projects/Win/vc12/cds.vcxproj.filters b/projects/Win/vc12/cds.vcxproj.filters index 2281455a..9c287647 100644 --- a/projects/Win/vc12/cds.vcxproj.filters +++ b/projects/Win/vc12/cds.vcxproj.filters @@ -148,11 +148,8 @@ {0a2328b4-ff6f-4afb-8de0-9884ae172fa9} - - {043c4eba-3bd4-4226-b214-e26f18b422a1} - - - {9c0f5739-8d9d-46c2-bb91-90ca5beecc6d} + + {3195cce2-1710-4b79-a1cf-6c7cea085fa3} @@ -1154,21 +1151,6 @@ Header Files\cds\gc - - Header Files\cds\gc\hp - - - Header Files\cds\gc\dhp - - - Header Files\cds\gc\dhp - - - Header Files\cds\gc\hp - - - Header Files\cds\gc\hp - Source Files @@ -1187,5 +1169,17 @@ Header Files\cds\gc\details + + Header Files\cds\gc\impl + + + Header Files\cds\gc\impl + + + Header Files\cds\gc\impl + + + Header Files\cds\gc\impl + \ No newline at end of file -- 2.34.1