2010.01.27 khizmax Introducing memory order constraint
*/
+//@cond
namespace cds {
- /**
- @page cds_garbage_collectors_comparison GC comparison
- @ingroup cds_garbage_collector
-
- <table>
- <tr>
- <th>Feature</th>
- <th>%cds::gc::HP</th>
- <th>%cds::gc::DHP</th>
- </tr>
- <tr>
- <td>Implementation quality</td>
- <td>stable</td>
- <td>stable</td>
- </tr>
- <tr>
- <td>Performance rank (1 - slowest, 5 - fastest)</td>
- <td>5</td>
- <td>4</td>
- </tr>
- <tr>
- <td>Max number of guarded (hazard) pointers per thread</td>
- <td>limited (specifies in GC object ctor)</td>
- <td>unlimited (dynamically allocated when needed)</td>
- </tr>
- <tr>
- <td>Max number of retired pointers<sup>1</sup></td>
- <td>bounded</td>
- <td>bounded</td>
- </tr>
- <tr>
- <td>Array of retired pointers</td>
- <td>preallocated for each thread, limited in size</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.
- */
-
/// Different safe memory reclamation schemas (garbage collectors)
/** @ingroup cds_garbage_collector
public:
/// Iterator
- typedef retired_vector_impl::iterator iterator;
+ typedef retired_vector_impl::iterator iterator;
/// Constructor
retired_vector( const cds::gc::hp::GarbageCollector& HzpMgr ) CDS_NOEXCEPT; // inline
/// 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)
- atomics::atomic<bool> m_bFree ; ///< true if record if free (not owned)
+ 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)
+ 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
*/
void DeletePtr( details::retired_ptr& p );
- //@cond
void detachAllThread();
- //@endcond
public:
/// Creates GarbageCollector singleton
} cast_ptr;
cast_ptr.p = p;
- uinion{
+ union{
void( *pFunc )(T *);
free_retired_ptr_func hpFunc;
} cast_func;
retirePtr( details::retired_ptr( cast_ptr.hp, cast_func.hpFunc ) );
*/
- retirePtr( details::retired_ptr( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc ) ) );
+ retirePtr( details::retired_ptr( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc )));
}
/// Places retired pointer \p into thread's array of retired pointer for deferred reclamation
}
}
- //@cond
void scan()
{
m_HzpManager.Scan( m_pHzpRec );
m_HzpManager.HelpScan( m_pHzpRec );
}
- //@endcond
};
/// Auto hp_guard.
*/
class guard
{
- //@cond
- details::hp_guard& m_hp ; ///< Hazard pointer guarded
+ details::hp_guard& m_hp ; ///< Hazard pointer guarded
ThreadGC& m_gc ; ///< Thread GC
- //@endcond
public:
typedef details::hp_guard::hazard_ptr hazard_ptr ; ///< Hazard pointer type
+
public:
/// Allocates HP guard from \p gc
guard( ThreadGC& gc )
return m_hp = p;
}
- //@cond
std::nullptr_t operator =(std::nullptr_t)
{
return m_hp = nullptr;
{
return m_hp;
}
- //@endcond
};
/// Auto-managed array of hazard pointers
} // namespace hp
}} // namespace cds::gc
+//@endcond
+//@cond
// Inlines
-#include <cds/gc/details/hp_inline.h>
+namespace cds {
+ namespace gc{ namespace hp { namespace details {
+
+ inline retired_vector::retired_vector( const cds::gc::hp::GarbageCollector& HzpMgr ) CDS_NOEXCEPT
+ : m_arr( HzpMgr.getMaxRetiredPtrCount() ),
+ m_nSize(0)
+ {}
+
+ inline hp_record::hp_record( const cds::gc::hp::GarbageCollector& HzpMgr )
+ : m_hzp( HzpMgr.getHazardPointerCount() ),
+ m_arrRetired( HzpMgr )
+ {}
+
+ }}} // namespace gc::hp::details
+} // namespace cds
+//@endcond
+
#if CDS_COMPILER == CDS_COMPILER_MSVC
# pragma warning(pop)