Removed TSan annotations, tuned memory ordering
[libcds.git] / cds / gc / impl / dhp_decl.h
index 333c6d7985544e54b22ce823414d227181b65b9c..b0bde8f0cb1853867099da9cd24de6d1e94851df 100644 (file)
@@ -1,7 +1,7 @@
 //$$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>
@@ -120,7 +120,8 @@ namespace cds { namespace gc {
 
         public:
             // Default ctor
-            Guard();   // inline in dhp_impl.h
+            Guard()
+            {}
 
             //@cond
             Guard( Guard const& ) = delete;
@@ -139,7 +140,7 @@ namespace cds { namespace gc {
             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 );
@@ -168,7 +169,7 @@ namespace cds { namespace gc {
             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;
@@ -259,7 +260,8 @@ namespace cds { namespace gc {
 
         public:
             // Default ctor
-            GuardArray();   // inline in dhp_impl.h
+            GuardArray()
+            {}
 
             //@cond
             GuardArray( GuardArray const& ) = delete;
@@ -280,8 +282,8 @@ namespace cds { namespace gc {
             {
                 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;
             }
@@ -308,8 +310,8 @@ namespace cds { namespace gc {
             {
                 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;
             }
@@ -513,7 +515,7 @@ namespace cds { namespace gc {
             /// Checks if the guarded pointer is \p nullptr
             bool empty() const CDS_NOEXCEPT
             {
-                return !m_guard.is_initialized() || m_guard.get() == nullptr;
+                return !m_guard.is_initialized() || m_guard.get( atomics::memory_order_relaxed ) == nullptr;
             }
 
             /// \p bool operator returns <tt>!empty()</tt>
@@ -529,8 +531,7 @@ namespace cds { namespace gc {
             */
             void release() CDS_NOEXCEPT
             {
-                if ( m_guard.is_initialized() )
-                    m_guard.clear();
+                free_guard();
             }
 
             //@cond
@@ -560,10 +561,20 @@ namespace cds { namespace gc {
         };
 
     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
@@ -576,9 +587,11 @@ namespace cds { namespace gc {
             );
         }
 
-        /// 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()
         {
@@ -588,11 +601,11 @@ namespace cds { namespace gc {
         /// 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
@@ -618,7 +631,7 @@ namespace cds { namespace gc {
             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 )
@@ -647,4 +660,4 @@ namespace cds { namespace gc {
 
 }} // namespace cds::gc
 
-#endif // #ifndef __CDS_GC_IMPL_DHP_DECL_H
+#endif // #ifndef CDSLIB_GC_IMPL_DHP_DECL_H