Remove ugly reinterpret_cast from HP GC
authorkhizmax <khizmax@gmail.com>
Mon, 17 Nov 2014 10:46:19 +0000 (13:46 +0300)
committerkhizmax <khizmax@gmail.com>
Mon, 17 Nov 2014 10:46:19 +0000 (13:46 +0300)
cds/gc/details/retired_ptr.h
src/hp_gc.cpp

index 850451e16adfd6b7f2028510c43ad1b850b7e5e6..1df4422a4f5720b93ecbadee25ef58b899e3398f 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <cds/details/defs.h>
 
+//@cond
 namespace cds { namespace gc {
     /// Common implementation details for any GC
     namespace details {
@@ -20,7 +21,10 @@ namespace cds { namespace gc {
             /// Pointer type
             typedef void *          pointer;
 
-            pointer                 m_p;        ///< retired pointer
+            union {
+                pointer                 m_p;        ///< retired pointer
+                uintptr_t               m_n;
+            };
             free_retired_ptr_func   m_funcFree; ///< pointer to the destructor function
 
             /// Comparison of two retired pointers
@@ -37,14 +41,14 @@ namespace cds { namespace gc {
 
             /// Ctor
             retired_ptr( pointer p, free_retired_ptr_func func ) CDS_NOEXCEPT
-                : m_p( p ),
-                m_funcFree( func )
+                : m_p( p )
+                m_funcFree( func )
             {}
 
             /// Typecasting ctor
             template <typename T>
             retired_ptr( T * p, void (* pFreeFunc)(T *)) CDS_NOEXCEPT
-                : m_p( reinterpret_cast<pointer>( p ) )
+                : m_p( reinterpret_cast<pointer>(p))
                 , m_funcFree( reinterpret_cast< free_retired_ptr_func >( pFreeFunc ))
             {}
 
@@ -68,7 +72,6 @@ namespace cds { namespace gc {
             }
         };
 
-        //@cond
         static inline bool operator <( const retired_ptr& p1, const retired_ptr& p2 ) CDS_NOEXCEPT
         {
             return retired_ptr::less( p1, p2 );
@@ -83,8 +86,8 @@ namespace cds { namespace gc {
         {
             return !(p1 == p2);
         }
-        //@endcond
     }  // namespace details
 }}   // namespace cds::gc
+//@endcond
 
 #endif // #ifndef __CDS_GC_DETAILS_RETIRED_PTR_H
index f256dee77405acabd8085c509a902e55ba91e7a9..05b5f748f50750b7dd537c920ae5083da90fdc00 100644 (file)
@@ -218,7 +218,7 @@ namespace cds { namespace gc {
             details::retired_vector::iterator itRetired     = pRec->m_arrRetired.begin();
             details::retired_vector::iterator itRetiredEnd  = pRec->m_arrRetired.end();
             for ( auto it = itRetired; it != itRetiredEnd; ++it ) {
-                if ( reinterpret_cast<uintptr_t>(it->m_p) & 1 ) {
+                if ( it->m_n & 1 ) {
                     // found a pointer with LSB bit set - use classic_scan
                     classic_scan( pRec );
                     return;
@@ -241,7 +241,7 @@ namespace cds { namespace gc {
                             details::retired_vector::iterator it = std::lower_bound( itRetired, itRetiredEnd, dummyRetired, cds::gc::details::retired_ptr::less );
                             if ( it != itRetiredEnd && it->m_p == hptr ) {
                                 // Mark retired pointer as guarded
-                                it->m_p = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(it->m_p) | 1);
+                                it->m_n |= 1;
                             }
                         }
                     }
@@ -251,11 +251,12 @@ namespace cds { namespace gc {
 
             // Move all marked pointers to head of array
             {
-                details::retired_vector::iterator itInsert = itRetired;
+                auto itInsert = itRetired;
                 for ( auto it = itRetired; it != itRetiredEnd; ++it ) {
-                    if ( reinterpret_cast<uintptr_t>(it->m_p) & 1 ) {
-                        it->m_p = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(it->m_p) & ~1);
-                        *itInsert = *it;
+                    if ( it->m_n & 1 ) {
+                        it->m_n &= ~1;
+                        if ( itInsert != it )
+                            *itInsert = *it;
                         ++itInsert;
                         CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_DeferredNode );
                     }