}
/// Returns pointer to the first item in the array
- value_type * top()
+ value_type * top() CDS_NOEXCEPT
{
return m_arr;
}
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 <typename T>
- retired_ptr( T * p, void (* pFreeFunc)(T *))
+ retired_ptr( T * p, void (* pFreeFunc)(T *)) CDS_NOEXCEPT
: m_p( reinterpret_cast<pointer>( 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;
};
//@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
#include <cds/cxx11_atomic.h>
#include <cds/details/allocator.h>
-#include <cds/gc/hp/details/hp_fwd.h>
#include <cds/gc/hp/details/hp_type.h>
//@cond
namespace cds {
namespace gc { namespace hp {
+ // forwards
+ class GarbageCollector;
+ class ThreadGC;
+
/// Hazard Pointer schema implementation details
namespace details {
/**
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 <typename HazardPointer>
- class HPGuardT: protected atomics::atomic<HazardPointer>
+ 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<hazard_ptr> base_class;
protected:
//@cond
- template <typename OtherHazardPointer, class Allocator> friend class HPAllocator;
+ template <class Allocator> 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 <typename T>
- T * operator =( T * p ) CDS_NOEXCEPT
+ */
+ template <typename T>
+ 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<hazard_ptr>(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;
/**
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 <typename T>
+ 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<hazard_ptr>(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<hazard_pointer> HPGuard;
-
/// Array of hazard pointers.
/**
Array of hazard-pointer. Placing a pointer into this array guards the pointer against reclamation.
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 <typename HazardPointer, size_t Count>
- class HPArrayT
+ template <size_t Count>
+ class hp_array
{
public:
- typedef HazardPointer hazard_ptr_type ; ///< Hazard pointer type
- typedef HPGuardT<hazard_ptr_type> 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 <typename OtherHazardPointer, class Allocator> friend class HPAllocator;
+ template <class Allocator> 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
}
};
- /// Specialization of HPArrayT class for hazard_pointer type
- template <size_t Count> using HPArray = HPArrayT<hazard_pointer, Count >;
-
/// Allocator of hazard pointers for the thread
/**
The hazard pointer array is the free-list of unused hazard pointer for the thread.
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 Allocator = CDS_DEFAULT_ALLOCATOR >
+ class hp_allocator
{
public:
- typedef HazardPointer hazard_ptr_type ; ///< type of hazard pointer
- typedef HPGuardT<hazard_ptr_type> 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
public:
/// Default ctor
- explicit HPAllocator(
+ explicit hp_allocator(
size_t nCapacity ///< max count of hazard pointer per thread
)
: m_arrHazardPtr( alloc_array( nCapacity ) )
}
/// Dtor
- ~HPAllocator()
+ ~hp_allocator()
{
allocator_impl().Delete( m_arrHazardPtr, capacity() );
}
Returns initialized object \p arr
*/
template <size_t Count>
- void alloc( HPArrayT<hazard_ptr_type, Count>& arr ) CDS_NOEXCEPT
+ void alloc( hp_array<Count>& arr ) CDS_NOEXCEPT
{
assert( m_nTop >= Count );
m_nTop -= Count;
Frees the array of hazard pointers allocated by previous call \p this->alloc.
*/
template <size_t Count>
- void free( const HPArrayT<hazard_ptr_type, Count>& arr ) CDS_NOEXCEPT
+ void free( hp_array<Count> const& arr ) CDS_NOEXCEPT
{
assert( m_nTop + Count <= capacity());
for ( size_t i = m_nTop; i < m_nTop + Count; ++i )
+++ /dev/null
-//$$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
/************************************************************************/
/* 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 )
{}
+++ /dev/null
-//$$CDS-header$$
-
-#ifndef __CDS_GC_HP_DETAILS_HP_RETIRED_H
-#define __CDS_GC_HP_DETAILS_HP_RETIRED_H
-
-#include <cds/gc/hp/details/hp_fwd.h>
-#include <cds/gc/hp/details/hp_type.h>
-
-#include <cds/details/bounded_array.h>
-
-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_ptr> 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
#ifndef __CDS_GC_HP_DETAILS_HP_TYPE_H
#define __CDS_GC_HP_DETAILS_HP_TYPE_H
-#include <cds/gc/details/retired_ptr.h>
+#include <cds/gc/details/retired_ptr.h> // free_retired_ptr_func
namespace cds {
namespace gc {
#ifndef __CDS_GC_HP_HP_H
#define __CDS_GC_HP_HP_H
-#include <vector>
#include <cds/cxx11_atomic.h>
#include <cds/os/thread.h>
-#include <cds/gc/hp/details/hp_fwd.h>
+#include <cds/details/bounded_array.h>
+
+#include <cds/gc/hp/details/hp_type.h>
#include <cds/gc/hp/details/hp_alloc.h>
-#include <cds/gc/hp/details/hp_retired.h>
#if CDS_COMPILER == CDS_COMPILER_MSVC
# pragma warning(push)
- [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_ptr> 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<hazard_pointer> 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
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
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
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<OS::ThreadId> m_idOwner ; ///< Owner thread id; 0 - the record is free (not owned)
//@cond
hplist_node( const GarbageCollector& HzpMgr )
- : HPRec( HzpMgr ),
+ : hp_record( HzpMgr ),
m_pNextNode( nullptr ),
m_idOwner( OS::c_NullThreadId ),
m_bFree( true )
}
/// 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
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
/**
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:
The function is called internally by Scan.
*/
- void HelpScan( details::HPRec * pThis );
+ void HelpScan( details::hp_record * pThis );
protected:
/// Classic scan algorithm
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
*/
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
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 );
/// Initializes HP guard array \p arr
template <size_t Count>
- void allocGuard( details::HPArray<Count>& arr )
+ void allocGuard( details::hp_array<Count>& arr )
{
assert( m_pHzpRec );
m_pHzpRec->m_hzp.alloc( arr );
/// Frees HP guard array \p arr
template <size_t Count>
- void freeGuard( details::HPArray<Count>& arr )
+ void freeGuard( details::hp_array<Count>& arr )
{
assert( m_pHzpRec );
m_pHzpRec->m_hzp.free( arr );
//@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.
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 )
/// 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 <size_t Count>
- class AutoHPArray: public details::HPArray<Count>
+ class AutoHPArray : public details::hp_array<Count>
{
ThreadGC& m_mgr ; ///< Thread GC
<ClInclude Include="..\..\..\cds\gc\dhp\dhp_impl.h" />\r
<ClInclude Include="..\..\..\cds\gc\guarded_ptr.h" />\r
<ClInclude Include="..\..\..\cds\gc\hp\details\hp_alloc.h" />\r
- <ClInclude Include="..\..\..\cds\gc\hp\details\hp_fwd.h" />\r
<ClInclude Include="..\..\..\cds\gc\hp\details\hp_inline.h" />\r
- <ClInclude Include="..\..\..\cds\gc\hp\details\hp_retired.h" />\r
<ClInclude Include="..\..\..\cds\gc\hp\details\hp_type.h" />\r
<ClInclude Include="..\..\..\cds\gc\hp\hp.h" />\r
<ClInclude Include="..\..\..\cds\gc\hp\hp_decl.h" />\r
<ClInclude Include="..\..\..\cds\gc\hp\details\hp_alloc.h">\r
<Filter>Header Files\cds\gc\hp</Filter>\r
</ClInclude>\r
- <ClInclude Include="..\..\..\cds\gc\hp\details\hp_fwd.h">\r
- <Filter>Header Files\cds\gc\hp</Filter>\r
- </ClInclude>\r
<ClInclude Include="..\..\..\cds\gc\hp\details\hp_inline.h">\r
<Filter>Header Files\cds\gc\hp</Filter>\r
</ClInclude>\r
- <ClInclude Include="..\..\..\cds\gc\hp\details\hp_retired.h">\r
- <Filter>Header Files\cds\gc\hp</Filter>\r
- </ClInclude>\r
<ClInclude Include="..\..\..\cds\gc\hp\details\hp_type.h">\r
<Filter>Header Files\cds\gc\hp</Filter>\r
</ClInclude>\r
p.free();
}
- details::HPRec * GarbageCollector::AllocateHPRec()
+ details::hp_record * GarbageCollector::AllocateHPRec()
{
CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_AllocHPRec );
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 );
}
}
- void GarbageCollector::classic_scan( details::HPRec * pRec )
+ void GarbageCollector::classic_scan( details::hp_record * pRec )
{
CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_ScanCallCount );
}
}
- void GarbageCollector::inplace_scan( details::HPRec * pRec )
+ void GarbageCollector::inplace_scan( details::hp_record * pRec )
{
CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_ScanCallCount );
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 );
}
}
- // 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;
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;