//$$CDS-header$$
-#ifndef __CDS_GC_IMPL_DHP_DECL_H
-#define __CDS_GC_IMPL_DHP_DECL_H
+#ifndef CDSLIB_GC_IMPL_DHP_DECL_H
+#define CDSLIB_GC_IMPL_DHP_DECL_H
#include <cds/gc/details/dhp.h>
#include <cds/details/marked_ptr.h>
public:
// Default ctor
- Guard(); // inline in dhp_impl.h
+ Guard()
+ {}
//@cond
Guard( Guard const& ) = delete;
template <typename T>
T protect( atomics::atomic<T> const& toGuard )
{
- T pCur = toGuard.load(atomics::memory_order_relaxed);
+ T pCur = toGuard.load(atomics::memory_order_acquire);
T pRet;
do {
pRet = assign( pCur );
template <typename T, class Func>
T protect( atomics::atomic<T> const& toGuard, Func f )
{
- T pCur = toGuard.load(atomics::memory_order_relaxed);
+ T pCur = toGuard.load(atomics::memory_order_acquire);
T pRet;
do {
pRet = pCur;
public:
// Default ctor
- GuardArray(); // inline in dhp_impl.h
+ GuardArray()
+ {}
//@cond
GuardArray( GuardArray const& ) = delete;
{
T pRet;
do {
- pRet = assign( nIndex, toGuard.load(atomics::memory_order_relaxed) );
- } while ( pRet != toGuard.load(atomics::memory_order_acquire));
+ pRet = assign( nIndex, toGuard.load(atomics::memory_order_acquire) );
+ } while ( pRet != toGuard.load(atomics::memory_order_relaxed));
return pRet;
}
{
T pRet;
do {
- assign( nIndex, f( pRet = toGuard.load(atomics::memory_order_relaxed) ));
- } while ( pRet != toGuard.load(atomics::memory_order_acquire));
+ assign( nIndex, f( pRet = toGuard.load(atomics::memory_order_acquire) ));
+ } while ( pRet != toGuard.load(atomics::memory_order_relaxed));
return pRet;
}
*/
void release() CDS_NOEXCEPT
{
- if ( m_guard.is_initialized() )
- m_guard.clear();
+ free_guard();
}
//@cond
};
public:
- /// Initializes dhp::GarbageCollector singleton
+ /// Initializes %DHP memory manager singleton
/**
- The constructor calls GarbageCollector::Construct with passed parameters.
- See dhp::GarbageCollector::Construct for explanation of parameters meaning.
+ Constructor creates and initializes %DHP global object.
+ %DHP object should be created before using CDS data structure based on \p %cds::gc::DHP GC. Usually,
+ it is created in the \p main() function.
+ After creating of global object you may use CDS data structures based on \p %cds::gc::DHP.
+
+ \par Parameters
+ - \p nLiberateThreshold - \p scan() threshold. When count of retired pointers reaches this value,
+ the \p scan() member function would be called for freeing retired pointers.
+ - \p nInitialThreadGuardCount - initial count of guard allocated for each thread.
+ When a thread is initialized the GC allocates local guard pool for the thread from 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.
*/
DHP(
size_t nLiberateThreshold = 1024
);
}
- /// Terminates dhp::GarbageCollector singleton
+ /// Destroys %DHP memory manager
/**
- The destructor calls \code dhp::GarbageCollector::Destruct() \endcode
+ The destructor destroys %DHP global object. After calling of this function you may \b NOT
+ use CDS data structures based on \p %cds::gc::DHP.
+ Usually, %DHP object is destroyed at the end of your \p main().
*/
~DHP()
{
/// Checks if count of hazard pointer is no less than \p nCountNeeded
/**
The function always returns \p true since the guard count is unlimited for
- \p gc::DHP garbage collector.
+ \p %gc::DHP garbage collector.
*/
- static CDS_CONSTEXPR bool check_available_guards(
+ static CDS_CONSTEXPR bool check_available_guards(
#ifdef CDS_DOXYGEN_INVOKED
- size_t nCountNeeded,
+ size_t nCountNeeded,
#else
size_t,
#endif
The function places pointer \p p to array of pointers ready for removing.
(so called retired pointer array). The pointer can be safely removed when no guarded pointer points to it.
- See gc::HP::retire for \p Disposer requirements.
+ See \p gc::HP::retire for \p Disposer requirements.
*/
template <class Disposer, typename T>
static void retire( T * p )
}} // namespace cds::gc
-#endif // #ifndef __CDS_GC_IMPL_DHP_DECL_H
+#endif // #ifndef CDSLIB_GC_IMPL_DHP_DECL_H