// From https://groups.google.com/d/msg/thread-sanitizer/SsrHB7FTnTk/mNTGNLQj-9cJ
#ifdef CDS_THREAD_SANITIZER_ENABLED
-# define CDS_TSAN_ANNOTATE_HAPPENS_BEFORE(addr) AnnotateHappensBefore(__FILE__, __LINE__, (void*)(addr))\r
-# define CDS_TSAN_ANNOTATE_HAPPENS_AFTER(addr) AnnotateHappensAfter(__FILE__, __LINE__, (void*)(addr))\r
+# define CDS_TSAN_ANNOTATE_HAPPENS_BEFORE(addr) AnnotateHappensBefore(__FILE__, __LINE__, reinterpret_cast<void*>(addr))\r
+# define CDS_TSAN_ANNOTATE_HAPPENS_AFTER(addr) AnnotateHappensAfter(__FILE__, __LINE__, reinterpret_cast<void*>(addr))\r
\r
# define CDS_TSAN_ANNOTATE_IGNORE_READS_BEGIN AnnotateIgnoreReadsBegin(__FILE__, __LINE__)\r
# define CDS_TSAN_ANNOTATE_IGNORE_READS_END AnnotateIgnoreReadsEnd(__FILE__, __LINE__)\r
template <typename Q>
static node_type * alloc_node( Q const& v )
{
- return cxx_node_allocator().New( v );
+ CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
+ node_type * p = cxx_node_allocator().New( v );
+ CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
+ return p;
}
template <typename... Args>
static node_type * alloc_node( Args&&... args )
{
- return cxx_node_allocator().MoveNew( std::forward<Args>(args)...);
+ CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
+ node_type * p = cxx_node_allocator().MoveNew( std::forward<Args>(args)...);
+ CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
+ return p;
}
static void free_node( node_type * pNode )
{
+ CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
cxx_node_allocator().Delete( pNode );
+ CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
}
struct node_disposer {
void operator()( value_type * v )
{
splitlist_node_type * p = static_cast<splitlist_node_type *>( node_traits::to_node_ptr( v ));
- if ( p->is_dummy() )
+ if ( p->is_dummy() ) {
+ CDS_TSAN_ANNOTATE_HAPPENS_BEFORE( p );
dummy_node_disposer<gc, typename traits::allocator>()( p );
- else
+ }
+ else {
+ CDS_TSAN_ANNOTATE_HAPPENS_BEFORE( v );
native_disposer()( v );
+ }
}
};
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
return false;
}
- pNext = pCur->m_pNext.load(memory_model::memory_order_acquire);
+ pNext = pCur->m_pNext.load(memory_model::memory_order_relaxed);
+ CDS_TSAN_ANNOTATE_HAPPENS_AFTER( pNext.ptr() );
pos.guards.assign( position::guard_next_item, node_traits::to_value_ptr( pNext.ptr() ));
- if ( pCur->m_pNext.load(memory_model::memory_order_relaxed).all() != pNext.all() ) {
+ if ( pCur->m_pNext.load(memory_model::memory_order_acquire).all() != pNext.all() ) {
bkoff();
goto try_again;
}
dummy_node_type * alloc_dummy_node( size_t nHash )
{
m_Stat.onHeadNodeAllocated();
- return dummy_node_allocator().New( nHash );
+ CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
+ dummy_node_type * p = dummy_node_allocator().New( nHash );
+ CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
+ return p;
}
void free_dummy_node( dummy_node_type * p )
{
+ CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
dummy_node_allocator().Delete( p );
+ CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
m_Stat.onHeadNodeFreed();
}