Removed TSan annotations, tuned memory ordering
authorkhizmax <libcds.dev@gmail.com>
Thu, 21 May 2015 05:58:10 +0000 (08:58 +0300)
committerkhizmax <libcds.dev@gmail.com>
Thu, 21 May 2015 05:58:10 +0000 (08:58 +0300)
21 files changed:
cds/container/details/skip_list_base.h
cds/details/allocator.h
cds/gc/impl/dhp_decl.h
cds/gc/impl/hp_decl.h
cds/intrusive/details/split_list_base.h
cds/intrusive/impl/michael_list.h
cds/intrusive/lazy_list_rcu.h
cds/intrusive/split_list_rcu.h
cds/memory/michael/allocator.h
cds/urcu/details/base.h
cds/urcu/details/gpb.h
cds/urcu/details/gpi.h
cds/urcu/details/gpt.h
cds/urcu/details/sig_buffered.h
cds/urcu/details/sig_threaded.h
cds/urcu/dispose_thread.h
tests/cppunit/thread.cpp
tests/unit/ellen_bintree_update_desc_pool.h
tests/unit/queue/intrusive_queue_reader_writer.cpp
tests/unit/stack/stack_intrusive_pushpop.cpp
tools/tsan-suppression [new file with mode: 0644]

index ed309c5214f6ea4d439d49199cf6ac8cfeb6bdff..e11ec367ab59be5c42dbaaef3d857223118ac463 100644 (file)
@@ -171,23 +171,19 @@ namespace cds { namespace container {
                 template <typename Q>
                 node_type * New( unsigned int nHeight, Q const& v )
                 {
-                    CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
                     unsigned char * pMem = alloc_space( nHeight );
                     node_type * p = new( pMem )
                         node_type( nHeight, nHeight > 1 ? reinterpret_cast<node_tower_item *>(pMem + c_nNodeSize) : nullptr, v );
-                    CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
                     return p;
                 }
 
                 template <typename... Args>
                 node_type * New( unsigned int nHeight, Args&&... args )
                 {
-                    CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
                     unsigned char * pMem = alloc_space( nHeight );
                     node_type * p = new( pMem )
                         node_type( nHeight, nHeight > 1 ? reinterpret_cast<node_tower_item *>(pMem + c_nNodeSize) : nullptr,
                         std::forward<Args>(args)... );
-                    CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
                     return p;
                 }
 
@@ -197,9 +193,7 @@ namespace cds { namespace container {
 
                     unsigned int nHeight = p->height();
                     node_allocator_type().destroy( p );
-                    CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
                     free_space( reinterpret_cast<unsigned char *>(p), nHeight );
-                    CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
                 }
             };
 
index cbc634c08deb0f8ee5b73e091fafacce6a35546f..0b8b36f55688a8b08d9d6dd0b32179f9975b8518 100644 (file)
@@ -42,52 +42,20 @@ namespace cds {
             template <typename... S>
             value_type *  New( S const&... src )
             {
-#           if CDS_THREAD_SANITIZER_ENABLED
-                if ( c_bStdAllocator ) {
-                    CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
-                }
-                value_type * pv = Construct( allocator_type::allocate(1), src... );
-                if ( c_bStdAllocator ) {
-                    CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
-                }
-                return pv;
-#           else
                 return Construct( allocator_type::allocate(1), src... );
-#           endif
             }
 
             /// Analogue of <tt>operator new T( std::forward<Args>(args)... )</tt> (move semantics)
             template <typename... Args>
             value_type * MoveNew( Args&&... args )
             {
-#           if CDS_THREAD_SANITIZER_ENABLED
-                if ( c_bStdAllocator ) {
-                    CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
-                }
-                value_type * pv = MoveConstruct( allocator_type::allocate(1), std::forward<Args>(args)... );
-                if ( c_bStdAllocator ) {
-                    CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
-                }
-                return pv;
-#           else
                 return MoveConstruct( allocator_type::allocate(1), std::forward<Args>(args)... );
-#           endif
             }
 
             /// Analogue of operator new T[\p nCount ]
             value_type * NewArray( size_t nCount )
             {
-#           if CDS_THREAD_SANITIZER_ENABLED
-                if ( c_bStdAllocator ) {
-                    CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
-                }
-#           endif
                 value_type * p = allocator_type::allocate( nCount );
-#           if CDS_THREAD_SANITIZER_ENABLED
-                if ( c_bStdAllocator ) {
-                    CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
-                }
-#           endif
                 for ( size_t i = 0; i < nCount; ++i )
                     Construct( p + i );
                 return p;
@@ -100,17 +68,7 @@ namespace cds {
             template <typename S>
             value_type * NewArray( size_t nCount, S const& src )
             {
-#           if CDS_THREAD_SANITIZER_ENABLED
-                if ( c_bStdAllocator ) {
-                    CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
-                }
-#           endif
                 value_type * p = allocator_type::allocate( nCount );
-#           if CDS_THREAD_SANITIZER_ENABLED
-                if ( c_bStdAllocator ) {
-                    CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
-                }
-#           endif
                 for ( size_t i = 0; i < nCount; ++i )
                     Construct( p + i, src );
                 return p;
@@ -140,22 +98,16 @@ namespace cds {
             /// Analogue of operator delete
             void Delete( value_type * p )
             {
-                // TSan false positive possible
-                CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
                 allocator_type::destroy( p );
                 allocator_type::deallocate( p, 1 );
-                CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
             }
 
             /// Analogue of operator delete []
             void Delete( value_type * p, size_t nCount )
             {
-                // TSan false positive possible
-                CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
                  for ( size_t i = 0; i < nCount; ++i )
                      allocator_type::destroy( p + i );
                 allocator_type::deallocate( p, nCount );
-                CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
             }
 
 #       if CDS_COMPILER == CDS_COMPILER_INTEL
@@ -170,10 +122,7 @@ namespace cds {
             template <typename... S>
             value_type * Construct( void * p, S const&... src )
             {
-                // TSan false positive possible
-                CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
                 value_type * pv = new( p ) value_type( src... );
-                CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
                 return pv;
             }
 
@@ -181,10 +130,7 @@ namespace cds {
             template <typename... Args>
             value_type * MoveConstruct( void * p, Args&&... args )
             {
-                // TSan false positive possible
-                CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
                 value_type * pv = new( p ) value_type( std::forward<Args>(args)... );
-                CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
                 return pv;
             }
 
@@ -202,18 +148,7 @@ namespace cds {
 
                 size_t const nPtrSize = ( nByteSize + sizeof(void *) - 1 ) / sizeof(void *);
                 typedef typename allocator_type::template rebind< void * >::other void_allocator;
-#           if CDS_THREAD_SANITIZER_ENABLED
-                if ( c_bStdAllocator ) {
-                    CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
-                }
-#           endif
-                void * p = void_allocator().allocate( nPtrSize );
-#           if CDS_THREAD_SANITIZER_ENABLED
-                if ( c_bStdAllocator ) {
-                    CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
-                }
-#           endif
-                return p;
+                return void_allocator().allocate( nPtrSize );
             }
             //@endcond
         };
index 4b88ace17a85e90ec29d131764edbeb4b79c35d5..b0bde8f0cb1853867099da9cd24de6d1e94851df 100644 (file)
@@ -140,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 );
@@ -169,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;
@@ -282,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;
             }
@@ -310,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;
             }
index 043006cfafaca75028779d9b6023314ddec39c85..302829cfe5f01e212851ee5295c582119e4266f3 100644 (file)
@@ -136,7 +136,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 );
@@ -165,7 +165,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;
@@ -276,8 +276,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;
             }
@@ -304,8 +304,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;
             }
index 494ea3639c8cc02047cae12ce7ec716826f3b2e4..94e11ca3c7d96a21b25b171f1a56b7405bfeefab 100644 (file)
@@ -712,11 +712,9 @@ namespace cds { namespace intrusive {
                     {
                         splitlist_node_type * p = static_cast<splitlist_node_type *>( node_traits::to_node_ptr( v ));
                         if ( p->is_dummy() ) {
-                            CDS_TSAN_ANNOTATE_HAPPENS_BEFORE( p );
                             dummy_node_disposer<gc, typename traits::allocator>()( p );
                         }
                         else {
-                            CDS_TSAN_ANNOTATE_HAPPENS_BEFORE( v );
                             native_disposer()( v );
                         }
                     }
index b49bb64b2c676bb04dc5ac27e678e02fc06b79a3..97023f6d0b2fddc9ff734265790ab6bef3f4e00d 100644 (file)
@@ -223,10 +223,8 @@ namespace cds { namespace intrusive {
         struct clean_disposer {
             void operator()( value_type * p )
             {
-                CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
                 michael_list::node_cleaner<gc, node_type, memory_model>()( node_traits::to_node_ptr( p ) );
                 disposer()( p );
-                CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
             }
         };
         //@endcond
@@ -256,7 +254,7 @@ namespace cds { namespace intrusive {
 
             // Mark the node (logical deleting)
             marked_node_ptr next(pos.pNext, 0);
-            if ( pos.pCur->m_pNext.compare_exchange_strong( next, marked_node_ptr(pos.pNext, 1), memory_model::memory_order_release, atomics::memory_order_relaxed )) {
+            if ( pos.pCur->m_pNext.compare_exchange_strong( next, marked_node_ptr(pos.pNext, 1), memory_model::memory_order_acq_rel, atomics::memory_order_relaxed )) {
                 // physical deletion may be performed by search function if it detects that a node is logically deleted (marked)
                 // CAS may be successful here or in other thread that searching something
                 marked_node_ptr cur(pos.pCur);
@@ -1071,9 +1069,9 @@ try_again:
             pPrev = &refHead;
             pNext = nullptr;
 
-            pCur = pPrev->load(memory_model::memory_order_relaxed);
+            pCur = pPrev->load(memory_model::memory_order_acquire);
             pos.guards.assign( position::guard_current_item, node_traits::to_value_ptr( pCur.ptr() ) );
-            if ( pPrev->load(memory_model::memory_order_acquire) != pCur.ptr() )
+            if ( pPrev->load(memory_model::memory_order_relaxed) != pCur.ptr() )
                 goto try_again;
 
             while ( true ) {
@@ -1084,15 +1082,14 @@ try_again:
                     return false;
                 }
 
-                pNext = pCur->m_pNext.load(memory_model::memory_order_relaxed);
-                CDS_TSAN_ANNOTATE_HAPPENS_AFTER( pNext.ptr() );
+                pNext = pCur->m_pNext.load(memory_model::memory_order_acquire);
                 pos.guards.assign( position::guard_next_item, node_traits::to_value_ptr( pNext.ptr() ));
-                if ( pCur->m_pNext.load(memory_model::memory_order_acquire).all() != pNext.all() ) {
+                if ( pCur->m_pNext.load(memory_model::memory_order_relaxed).all() != pNext.all() ) {
                     bkoff();
                     goto try_again;
                 }
 
-                if ( pPrev->load(memory_model::memory_order_acquire).all() != pCur.ptr() ) {
+                if ( pPrev->load(memory_model::memory_order_relaxed).all() != pCur.ptr() ) {
                     bkoff();
                     goto try_again;
                 }
index a62cf157ed16c3172e210bd2172fe0107eb47abf..bd76c69488273f2ef024afc667aa7d71d4dc79d9 100644 (file)
@@ -846,13 +846,21 @@ namespace cds { namespace intrusive {
             return insert_at( pHead, *node_traits::to_value_ptr( pNode ) );
         }
 
-        bool insert_at( node_type * pHead, value_type& val, bool bLock = true )
+        bool insert_at( node_type * pHead, value_type& val )
         {
+            rcu_lock l;
+            return insert_at_locked( pHead, val );
+        }
+
+        bool insert_at_locked( node_type * pHead, value_type& val )
+        {
+            // RCU lock should be locked!!!
+            assert( gc::is_locked() );
+
             link_checker::is_empty( node_traits::to_node_ptr( val ) );
             position pos;
             key_comparator  cmp;
 
-            rcu_lock l( bLock );
             while ( true ) {
                 search( pHead, val, pos );
                 {
@@ -900,22 +908,31 @@ namespace cds { namespace intrusive {
             }
         }
 
-        iterator insert_at_( node_type * pHead, value_type& val, bool bLock = true )
+        iterator insert_at_( node_type * pHead, value_type& val )
         {
-            rcu_lock l( bLock );
-            if ( insert_at( pHead, val, false ))
+            rcu_lock l;
+            if ( insert_at_locked( pHead, val ))
                 return iterator( node_traits::to_node_ptr( val ));
             return end();
         }
 
 
         template <typename Func>
-        std::pair<iterator, bool> ensure_at_( node_type * pHead, value_type& val, Func func, bool bLock = true )
+        std::pair<iterator, bool> ensure_at_( node_type * pHead, value_type& val, Func func )
+        {
+            rcu_lock l;
+            return ensure_at_locked( pHead, val, func );
+        }
+
+        template <typename Func>
+        std::pair<iterator, bool> ensure_at_locked( node_type * pHead, value_type& val, Func func )
         {
+            // RCU lock should be locked!!!
+            assert( gc::is_locked() );
+
             position pos;
             key_comparator  cmp;
 
-            rcu_lock l( bLock );
             while ( true ) {
                 search( pHead, val, pos );
                 {
@@ -942,10 +959,10 @@ namespace cds { namespace intrusive {
         }
 
         template <typename Func>
-        std::pair<bool, bool> ensure_at( node_type * pHead, value_type& val, Func func, bool bLock = true )
+        std::pair<bool, bool> ensure_at( node_type * pHead, value_type& val, Func func )
         {
-            rcu_lock l( bLock );
-            std::pair<iterator, bool> ret = ensure_at_( pHead, val, func, false );
+            rcu_lock l;
+            std::pair<iterator, bool> ret = ensure_at_locked( pHead, val, func );
             return std::make_pair( ret.first != end(), ret.second );
         }
 
@@ -1072,11 +1089,11 @@ namespace cds { namespace intrusive {
         }
 
         template <typename Q, typename Compare, typename Func>
-        bool find_at( node_type * pHead, Q& val, Compare cmp, Func f, bool bLock = true ) const
+        bool find_at( node_type * pHead, Q& val, Compare cmp, Func f ) const
         {
             position pos;
 
-            rcu_lock l( bLock );
+            rcu_lock l;
             search( pHead, val, pos, cmp );
             if ( pos.pCur != &m_Tail ) {
                 std::unique_lock< typename node_type::lock_type> al( pos.pCur->m_Lock );
index 7c8618f7e0c3b86f5fb59d68c7913d313c3e31c7..3ba404927bdfff5b99850752ebfbed13e295c2e7 100644 (file)
@@ -519,10 +519,7 @@ namespace cds { namespace intrusive {
             dummy_node_type * pHead = get_bucket( nHash );
             assert( pHead != nullptr );
 
-            // TSan false positive: hash is read-only, will be ordered when we insert a node
-            CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
             node_traits::to_node_ptr( val )->m_nHash = split_list::regular_hash( nHash );
-            CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
 
             if ( m_List.insert_at( pHead, val )) {
                 inc_item_count();
@@ -561,10 +558,7 @@ namespace cds { namespace intrusive {
             dummy_node_type * pHead = get_bucket( nHash );
             assert( pHead != nullptr );
 
-            // TSan false positive: hash is read-only, will be ordered when we insert a node
-            CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
             node_traits::to_node_ptr( val )->m_nHash = split_list::regular_hash( nHash );
-            CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
 
             if ( m_List.insert_at( pHead, val, f )) {
                 inc_item_count();
@@ -609,10 +603,7 @@ namespace cds { namespace intrusive {
             dummy_node_type * pHead = get_bucket( nHash );
             assert( pHead != nullptr );
 
-            // TSan false positive: hash is read-only, will be ordered when we insert a node
-            CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
             node_traits::to_node_ptr( val )->m_nHash = split_list::regular_hash( nHash );
-            CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
 
             std::pair<bool, bool> bRet = m_List.ensure_at( pHead, val, func );
             if ( bRet.first && bRet.second ) {
index c4336d7ac3ca196b42570cad061c62d224ebcdc2..0366e55ac2b3b1514c8d8312df99e22874b0e237 100644 (file)
@@ -60,17 +60,13 @@ namespace michael {
         /// Allocates memory block of \p nSize bytes (\p malloc wrapper)
         static void * alloc( size_t nSize )
         {
-            CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
             void * p = ::malloc( nSize );
-            CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
             return p;
         }
         /// Returning memory block to the system (\p free wrapper)
         static void free( void * p )
         {
-            CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
             ::free( p );
-            CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
         }
     };
 
@@ -1226,10 +1222,8 @@ namespace michael {
                 newAnchor = oldAnchor = pDesc->anchor.load(atomics::memory_order_acquire);
 
                 assert( oldAnchor.avail < pDesc->nCapacity );
-                CDS_TSAN_ANNOTATE_IGNORE_READS_BEGIN;
                 pAddr = pDesc->pSB + oldAnchor.avail * (unsigned long long) pDesc->nBlockSize;
                 newAnchor.avail = reinterpret_cast<free_block_header *>( pAddr )->nNextFree;
-                CDS_TSAN_ANNOTATE_IGNORE_READS_END;
                 newAnchor.tag += 1;
 
                 if ( oldActive.credits() == 0 ) {
@@ -1310,10 +1304,8 @@ namespace michael {
                 newAnchor = oldAnchor = pDesc->anchor.load(atomics::memory_order_acquire);
 
                 assert( oldAnchor.avail < pDesc->nCapacity );
-                CDS_TSAN_ANNOTATE_IGNORE_READS_BEGIN;
                 pAddr = pDesc->pSB + oldAnchor.avail * pDesc->nBlockSize;
                 newAnchor.avail = reinterpret_cast<free_block_header *>( pAddr )->nNextFree;
-                CDS_TSAN_ANNOTATE_IGNORE_READS_END;
                 ++newAnchor.tag;
             } while ( !pDesc->anchor.compare_exchange_strong(oldAnchor, newAnchor, atomics::memory_order_release, atomics::memory_order_relaxed) );
 
@@ -1350,13 +1342,11 @@ namespace michael {
             byte * pEnd = pDesc->pSB + pDesc->nCapacity * pDesc->nBlockSize;
             unsigned int nNext = 0;
             const unsigned int nBlockSize = pDesc->nBlockSize;
-            CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
             for ( byte * p = pDesc->pSB; p < pEnd; p += nBlockSize ) {
                 reinterpret_cast<block_header *>( p )->set( pDesc, 0 );
                 reinterpret_cast<free_block_header *>( p )->nNextFree = ++nNext;
             }
             reinterpret_cast<free_block_header *>( pEnd - nBlockSize )->nNextFree = 0;
-            CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
 
             active_tag newActive;
             newActive.set( pDesc, ( (pDesc->nCapacity - 1 < active_tag::c_nMaxCredits) ? pDesc->nCapacity - 1 : active_tag::c_nMaxCredits ) - 1 );
index 37864bd735cd0f85e20afc713a8f08c4687f8a47..76420833334d5f6b20d2403cf200733de4db23a1 100644 (file)
@@ -407,19 +407,15 @@ namespace cds {
                 typedef ThreadGC                    thread_gc;
                 typedef typename thread_gc::rcu_tag rcu_tag;
 
-                bool m_bLocked;
             public:
-                scoped_lock(bool bLock = true)
-                    : m_bLocked( bLock )
+                scoped_lock()
                 {
-                    if ( bLock )
-                        thread_gc::access_lock();
+                    thread_gc::access_lock();
                 }
 
                 ~scoped_lock()
                 {
-                    if ( m_bLocked )
-                        thread_gc::access_unlock();
+                    thread_gc::access_unlock();
                 }
             };
             //@endcond
index 023c26387f820d1f043f2d16a236e0af9e416c49..229aded845a53e96e00d643fc5bc8c99a860e255 100644 (file)
@@ -108,9 +108,7 @@ namespace cds { namespace urcu {
             epoch_retired_ptr p;
             while ( m_Buffer.pop( p )) {
                 if ( p.m_nEpoch <= nEpoch ) {
-                    CDS_TSAN_ANNOTATE_IGNORE_RW_BEGIN;
                     p.free();
-                    CDS_TSAN_ANNOTATE_IGNORE_RW_END;
                 }
                 else {
                     push_buffer( p );
@@ -126,9 +124,7 @@ namespace cds { namespace urcu {
             if ( !bPushed || m_Buffer.size() >= capacity() ) {
                 synchronize();
                 if ( !bPushed ) {
-                    CDS_TSAN_ANNOTATE_IGNORE_RW_BEGIN;
                     ep.free();
-                    CDS_TSAN_ANNOTATE_IGNORE_RW_END;
                 }
                 return true;
             }
index 783a3064d3a8394fdfcba36b5723ef76119aabf4..1e5426ba0be212c90641f8110104b9eb7b210110 100644 (file)
@@ -112,9 +112,9 @@ namespace cds { namespace urcu {
         {
             synchronize();
             if ( p.m_p ) {
-                CDS_TSAN_ANNOTATE_IGNORE_RW_BEGIN;
+                // TSan ignores atomic_thread_fence in synchronize()
+                //CDS_TSAN_ANNOTATE_HAPPENS_BEFORE( p.m_p );
                 p.free();
-                CDS_TSAN_ANNOTATE_IGNORE_RW_END;
             }
         }
 
@@ -127,8 +127,11 @@ namespace cds { namespace urcu {
                 while ( itFirst != itLast ) {
                     retired_ptr p( *itFirst );
                     ++itFirst;
-                    if ( p.m_p )
+                    if ( p.m_p ) {
+                        // TSan ignores atomic_thread_fence in synchronize()
+                        //CDS_TSAN_ANNOTATE_HAPPENS_BEFORE( p.m_p );
                         p.free();
+                    }
                 }
             }
         }
index 84d2c1a83ae6ebd78d051b77fecbeb2264cfcc26..30bb1ebb0eaceff60ec99cac5361b4ad3d1420df 100644 (file)
@@ -114,9 +114,7 @@ namespace cds { namespace urcu {
             if ( !bPushed || m_Buffer.size() >= capacity() ) {
                 synchronize();
                 if ( !bPushed ) {
-                    CDS_TSAN_ANNOTATE_IGNORE_RW_BEGIN;
                     p.free();
-                    CDS_TSAN_ANNOTATE_IGNORE_RW_END;
                 }
                 return true;
             }
index bb0e0c5d6ba105eb36133ede27597cd82ab72232..874092ea6eeb171b23665a6b65f87b0ebfaae79f 100644 (file)
@@ -105,9 +105,7 @@ namespace cds { namespace urcu {
             epoch_retired_ptr p;
             while ( m_Buffer.pop( p )) {
                 if ( p.m_nEpoch <= nEpoch ) {
-                    CDS_TSAN_ANNOTATE_IGNORE_RW_BEGIN;
                     p.free();
-                    CDS_TSAN_ANNOTATE_IGNORE_RW_END;
                 }
                 else {
                     push_buffer( p );
@@ -122,9 +120,7 @@ namespace cds { namespace urcu {
             if ( !bPushed || m_Buffer.size() >= capacity() ) {
                 synchronize();
                 if ( !bPushed ) {
-                    CDS_TSAN_ANNOTATE_IGNORE_RW_BEGIN;
                     ep.free();
-                    CDS_TSAN_ANNOTATE_IGNORE_RW_END;
                 }
                 return true;
             }
index 17d0152531f1c98c149850100a3a8fbe697c9a5a..ffc8b49092ac44bf343aaa312a64d69e5d86199f 100644 (file)
@@ -111,9 +111,7 @@ namespace cds { namespace urcu {
             if ( !bPushed || m_Buffer.size() >= capacity() ) {
                 synchronize();
                 if ( !bPushed ) {
-                    CDS_TSAN_ANNOTATE_IGNORE_RW_BEGIN;
                     p.free();
-                    CDS_TSAN_ANNOTATE_IGNORE_RW_END;
                 }
                 return true;
             }
index 46baa8fa7c67029b5b83e19daa348074eda07b05..553a4d6b0e60f9c60e19b5726d432c7a8285b2bc 100644 (file)
@@ -103,9 +103,7 @@ namespace cds { namespace urcu {
             epoch_retired_ptr p;
             while ( pBuf->pop( p ) ) {
                 if ( p.m_nEpoch <= nCurEpoch ) {
-                    CDS_TSAN_ANNOTATE_IGNORE_RW_BEGIN;
                     p.free();
-                    CDS_TSAN_ANNOTATE_IGNORE_RW_END;
                 }
                 else {
                     pBuf->push( p );
index bac98015296510ea890e021090ed2e35701cb7c9..69f8e86287239d6c60a2b83e6b2bd437c28c94c6 100644 (file)
@@ -43,16 +43,12 @@ namespace CppUnitMini {
 
     ThreadPool::~ThreadPool()
     {
-        CDS_TSAN_ANNOTATE_IGNORE_RW_BEGIN;
-
         delete m_pBarrierStart;
         delete m_pBarrierDone;
 
         for ( size_t i = 0; i < m_arrThreads.size(); ++i )
             delete m_arrThreads[i];
         m_arrThreads.resize( 0 );
-
-        CDS_TSAN_ANNOTATE_IGNORE_RW_END;
     }
 
     void    ThreadPool::add( TestThread * pThread, size_t nCount )
index e8158e9f622254854edca88863447710202f896f..f5fec3024c73f082e18ef497d33b0933d9a99071 100644 (file)
@@ -87,9 +87,7 @@ namespace ellen_bintree_pool {
         T * allocate( size_t n, void const * pHint = nullptr )
         {
             internal_node_counter::onAlloc();
-            CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
             T * p = base_class::allocate( n, pHint );
-            CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
             return p;
         }
 
index a4f0e734cc5e740f1d3d59dd00f47dc5a79e1602..b5ad38c48f5e01b86e3f1dca14ad25c5f3ac1438 100644 (file)
@@ -168,14 +168,12 @@ namespace queue {
                 while ( true ) {
                     typename Queue::value_type * p = m_Queue.pop();
                     if ( p ) {
-                        CDS_TSAN_ANNOTATE_IGNORE_RW_BEGIN;
                         p->nConsumer = m_nThreadNo;
                         ++m_nPopped;
                         if ( p->nWriterNo < nTotalWriters )
                             m_WriterData[ p->nWriterNo ].push_back( p->nNo );
                         else
                             ++m_nBadWriter;
-                        CDS_TSAN_ANNOTATE_IGNORE_RW_END;
                     }
                     else {
                         ++m_nPopEmpty;
index 2ed56cd9ddbd1640c50ed268864d203c1cac17e6..4369bf1c6bdcebc2889c2e1919b092351c477ec8 100644 (file)
@@ -149,14 +149,12 @@ namespace istack {
                 while ( !(getTest().m_nWorkingProducers.load(atomics::memory_order_acquire) == 0 && m_Stack.empty()) ) {
                     typename Stack::value_type * p = m_Stack.pop();
                     if ( p ) {
-                        CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
                         p->nConsumer = m_nThreadNo;
                         ++m_nPopCount;
                         if ( p->nNo < sizeof(m_arrPop)/sizeof(m_arrPop[0]) )
                             ++m_arrPop[p->nNo];
                         else
                             ++m_nDirtyPop;
-                        CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
                     }
                     else
                         ++m_nPopEmpty;
diff --git a/tools/tsan-suppression b/tools/tsan-suppression
new file mode 100644 (file)
index 0000000..ba02f0c
--- /dev/null
@@ -0,0 +1,4 @@
+
+
+# Boost race [?] in test framework. Do not affect to libcds
+race:CppUnitMini::ThreadPool::~ThreadPool