Merge branch 'check' into dev
[libcds.git] / cds / gc / details / hp.h
index 0e9f0c0d9a3d8dcf9ff748970a8024cd3e21e146..ab475a3acabbf1595a824e2909b9a5206652d8ff 100644 (file)
         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
 
@@ -124,7 +80,7 @@ namespace cds {
 
             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
@@ -282,11 +238,10 @@ namespace cds {
             /// 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 ),
@@ -299,7 +254,6 @@ namespace cds {
                     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
@@ -342,9 +296,7 @@ namespace cds {
             */
             void                DeletePtr( details::retired_ptr& p );
 
-            //@cond
             void detachAllThread();
-            //@endcond
 
         public:
             /// Creates GarbageCollector singleton
@@ -624,7 +576,7 @@ namespace cds {
                 } cast_ptr;
                 cast_ptr.p = p;
 
-                uinion{
+                union{
                     void( *pFunc )(T *);
                     free_retired_ptr_func hpFunc;
                 } cast_func;
@@ -632,7 +584,7 @@ namespace cds {
 
                 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
@@ -646,13 +598,11 @@ namespace cds {
                 }
             }
 
-            //@cond
             void scan()
             {
                 m_HzpManager.Scan( m_pHzpRec );
                 m_HzpManager.HelpScan( m_pHzpRec );
             }
-            //@endcond
         };
 
         /// Auto hp_guard.
@@ -663,13 +613,12 @@ namespace cds {
         */
         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 )
@@ -705,7 +654,6 @@ namespace cds {
                 return m_hp = p;
             }
 
-            //@cond
             std::nullptr_t operator =(std::nullptr_t)
             {
                 return m_hp = nullptr;
@@ -715,7 +663,6 @@ namespace cds {
             {
                 return m_hp;
             }
-            //@endcond
         };
 
         /// Auto-managed array of hazard pointers
@@ -755,9 +702,27 @@ namespace cds {
 
     }   // 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)