size_t m_nGuardCount ; ///< Total guard count
size_t m_nFreeGuardCount ; ///< Count of free guard
+ //@cond
InternalState()
: m_nGuardCount(0)
, m_nFreeGuardCount(0)
return *this;
}
+ //@endcond
};
private:
m_gc.retirePtr( p, pFunc );
}
+ /// Run retiring cycle
void scan()
{
m_gc.scan();
atomics::atomic<OS::ThreadId> m_idOwner; ///< Owner thread id; 0 - the record is free (not owned)
atomics::atomic<bool> m_bFree; ///< true if record if free (not owned)
+ //@cond
hplist_node( const GarbageCollector& HzpMgr )
: hp_record( HzpMgr ),
m_pNextNode( nullptr ),
assert( m_idOwner.load( atomics::memory_order_relaxed ) == OS::c_NullThreadId );
assert( m_bFree.load(atomics::memory_order_relaxed) );
}
+ //@endcond
};
atomics::atomic<hplist_node *> m_pListHead ; ///< Head of GC list
}
}
+ /// Run retiring scan cycle
void scan()
{
m_HzpManager.Scan( m_pHzpRec );
return m_hp = p;
}
+ //@cond
std::nullptr_t operator =(std::nullptr_t)
{
return m_hp = nullptr;
}
+ //@endcond
+ /// Get raw guarded pointer
hazard_ptr get() const
{
return m_hp;
</tr>
<tr>
<td>Array of retired pointers</td>
- <td>preallocated for each thread, limited in size</td>
+ <td>preallocated for each thread, size is limited</td>
<td>global for the entire process, unlimited (dynamically allocated when needed)</td>
</tr>
- <tr>
- <td>Support direct pointer to item of lock-free container (useful for iterators)</td>
- <td>not supported</td>
- <td>not supported</td>
- </tr>
</table>
<sup>1</sup>Unbounded count of retired pointer means a possibility of memory exhaustion.
};
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(
#ifdef CDS_DOXYGEN_INVOKED
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 )
classic = hp::classic, ///< classic scan as described in Michael's papers
inplace = hp::inplace ///< inplace scan without allocation
};
- /// Initializes hp::GarbageCollector singleton
+ /// Initializes %HP singleton
/**
The constructor initializes GC singleton with passed parameters.
If GC instance is not exist then the function creates the instance.
Otherwise it does nothing.
- The Michael's HP reclamation schema depends of three parameters:
+ The Michael's %HP reclamation schema depends of three parameters:
- \p nHazardPtrCount - hazard pointer count per thread. Usually it is small number (up to 10) depending from
the data structure algorithms. By default, if \p nHazardPtrCount = 0, the function
uses maximum of the hazard pointer count for CDS library.
/// Terminates GC singleton
/**
- The destructor calls \code hp::GarbageCollector::Destruct( true ) \endcode
+ The destructor destroys %HP global object. After calling of this function you may \b NOT
+ use CDS data structures based on \p %cds::gc::HP.
+ Usually, %HP object is destroyed at the end of your \p main().
*/
~HP()
{