cds  2.3.1
cds::gc::DHP Class Reference

Dynamic (adaptie) Hazard Pointer SMR. More...

#include <cds/gc/dhp.h>

Data Structures

class  Guard
 Dynamic Hazard Pointer guard. More...
 
class  GuardArray
 Array of Dynamic Hazard Pointer guards. More...
 
class  guarded_ptr
 Guarded pointer. More...
 

Public Types

typedef void * guarded_pointer
 Native guarded pointer type.
 
template<typename T >
using atomic_ref = atomics::atomic< T * >
 Atomic reference.
 
template<typename T >
using atomic_type = atomics::atomic< T >
 Atomic type.
 
template<typename MarkedPtr >
using atomic_marked_ptr = atomics::atomic< MarkedPtr >
 Atomic marked pointer.
 
typedef dhp::stat stat
 Internal statistics.
 

Public Member Functions

 DHP (size_t nInitialHazardPtrCount=16)
 Initializes DHP memory manager singleton. More...
 
 ~DHP ()
 Destroys DHP memory manager. More...
 

Static Public Member Functions

static constexpr bool check_available_guards (size_t nCountNeeded,)
 Checks if count of hazard pointer is no less than nCountNeeded. More...
 
static void set_memory_allocator (void *(*alloc_func)(size_t size), void(*free_func)(void *p))
 Set memory management functions. More...
 
template<typename T >
static void retire (T *p, void(*func)(void *))
 Retire pointer p with function pFunc. More...
 
template<class Disposer , typename T >
static void retire (T *p)
 Retire pointer p with functor of type Disposer. More...
 
static bool isUsed ()
 Checks if Dynamic Hazard Pointer GC is constructed and may be used.
 
static void scan ()
 Forced GC cycle call for current thread. More...
 
static void force_dispose ()
 Synonym for scan()
 
static void statistics (stat &st)
 Returns internal statistics. More...
 
static CDS_EXPORT_API stat const & postmortem_statistics ()
 Returns post-mortem statistics. More...
 

Detailed Description

Dynamic (adaptie) Hazard Pointer SMR.

Implementation of Dynamic (adaptive) Hazard Pointer SMR

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"

DHP is an adaptive variant of classic cds::gc::HP, see Compare HP implementation

Note
Internally, DHP depends on free-list implementation. There are DCAS-based free-list cds::intrusive::TaggedFreeList and more complicated CAS-based free-list cds::intrusive::FreeList. For x86 architecture and GCC/clang, libcds selects appropriate free-list based on -mcx16 compiler flag. You may manually disable DCAS support specifying -DCDS_DISABLE_128BIT_ATOMIC for 64bit build or -DCDS_DISABLE_64BIT_ATOMIC for 32bit build in compiler command line. All your projects and libcds MUST be compiled with the same flags - either with DCAS support or without it. For MS VC++ compiler DCAS is not supported.

See How to use section for details how to apply SMR.

Constructor & Destructor Documentation

◆ DHP()

cds::gc::DHP::DHP ( size_t  nInitialHazardPtrCount = 16)
inlineexplicit

Initializes DHP memory manager singleton.

Constructor creates and initializes DHP global object. DHP object should be created before using CDS data structure based on cds::gc::DHP. Usually, it is created in the beginning of main() function. After creating of global object you may use CDS data structures based on cds::gc::DHP.

nInitialThreadGuardCount - initial count of guard allocated for each thread. When a thread is initialized the GC allocates local guard pool for the thread from a common guard pool. By perforce the local thread's guard pool is grown automatically from common pool. When the thread terminated its guard pool is backed to common GC's pool.

Parameters
nInitialHazardPtrCountInitial number of hazard pointer per thread

◆ ~DHP()

cds::gc::DHP::~DHP ( )
inline

Destroys DHP memory manager.

The destructor destroys DHP global object. After calling of this function you may NOT use CDS data structures based on cds::gc::DHP. Usually, DHP object is destroyed at the end of your main().

Member Function Documentation

◆ check_available_guards()

static constexpr bool cds::gc::DHP::check_available_guards ( size_t  nCountNeeded)
inlinestatic

Checks if count of hazard pointer is no less than nCountNeeded.

The function always returns true since the guard count is unlimited for gc::DHP garbage collector.

◆ postmortem_statistics()

static CDS_EXPORT_API stat const& cds::gc::DHP::postmortem_statistics ( )
static

Returns post-mortem statistics.

Post-mortem statistics is gathered in the DHP object destructor and can be accessible after destructing the global DHP object.

Note
Internal statistics is available only if you compile libcds and your program with -DCDS_ENABLE_HPSTAT.

Usage:

int main()
{
{
// Initialize DHP SMR
cds::gc::DHP dhp;
// deal with DHP-based data structured
// ...
}
// DHP object destroyed
// Get total post-mortem statistics
printf( "DHP statistics:\n"
" thread count = %llu\n"
" guard allocated = %llu\n"
" guard freed = %llu\n"
" retired data count = %llu\n"
" free data count = %llu\n"
" scan() call count = %llu\n"
" help_scan() call count = %llu\n",
);
}

◆ retire() [1/2]

template<typename T >
static void cds::gc::DHP::retire ( T *  p,
void(*)(void *)  func 
)
inlinestatic

Retire pointer p with function pFunc.

The function places pointer p to array of pointers ready for removing. (so called retired pointer array). The pointer can be safely removed when no hazard pointer points to it. func is a disposer: when p can be safely removed, func is called.

◆ retire() [2/2]

template<class Disposer , typename T >
static void cds::gc::DHP::retire ( T *  p)
inlinestatic

Retire pointer p with functor of type Disposer.

The function places pointer p to array of pointers ready for removing. (so called retired pointer array). The pointer can be safely removed when no hazard pointer points to it.

Deleting the pointer is an invocation of some object of type Disposer; the interface of Disposer is:

template <typename T>
struct disposer {
void operator()( T * p ) ; // disposing operator
};

Since the functor call can happen at any time after retire() call, additional restrictions are imposed to Disposer type:

  • it should be stateless functor
  • it should be default-constructible
  • the result of functor call with argument p should not depend on where the functor will be called.
Examples:
Operator delete functor:
template <typename T>
struct disposer {
void operator ()( T * p ) {
delete p;
}
};
// How to call HP::retire method
int * p = new int;
// ... use p in lock-free manner
cds::gc::DHP::retire<disposer>( p ) ; // place p to retired pointer array of DHP SMR

Functor based on std::allocator :

template <typename Alloc = std::allocator<int> >
struct disposer {
template <typename T>
void operator()( T * p ) {
typedef typename Alloc::templare rebind<T>::other alloc_t;
alloc_t a;
a.destroy( p );
a.deallocate( p, 1 );
}
};

◆ scan()

static void cds::gc::DHP::scan ( )
inlinestatic

Forced GC cycle call for current thread.

Usually, this function should not be called directly.

◆ set_memory_allocator()

static void cds::gc::DHP::set_memory_allocator ( void *(*)(size_t size)  alloc_func,
void(*)(void *p)  free_func 
)
inlinestatic

Set memory management functions.

Note
This function may be called BEFORE creating an instance of Dynamic Hazard Pointer SMR

SMR object allocates some memory for thread-specific data and for creating SMR object. By default, a standard new and delete operators are used for this.

Parameters
alloc_funcmalloc() function
free_funcfree() function

◆ statistics()

static void cds::gc::DHP::statistics ( stat st)
inlinestatic

Returns internal statistics.

The function clears st before gathering statistics.

Note
Internal statistics is available only if you compile libcds and your program with -DCDS_ENABLE_HPSTAT.

The documentation for this class was generated from the following file:

cds 2.3.1 Developed by Maxim Khizhinsky aka khizmax 2007 - 2017
Autogenerated Fri Sep 1 2017 08:47:18 by Doxygen 1.8.13