CDS_TSAN_ANNOTATE_IGNORE_READS_END
# define CDS_TSAN_ANNOTATE_NEW_MEMORY( addr, sz ) AnnotateNewMemory( (char *) __FILE__, __LINE__, reinterpret_cast<void *>(addr), sz )
+# define CDS_TSAN_ANNOTATE_MUTEX_CREATE( addr ) AnnotateRWLockCreate( __FILE__, __LINE__, reinterpret_cast<void *>(addr))
+# define CDS_TSAN_ANNOTATE_MUTEX_DESTROY( addr ) AnnotateRWLockdESTROY( __FILE__, __LINE__, reinterpret_cast<void *>(addr))
+ // must be called after actual acquire
# define CDS_TSAN_ANNOTATE_MUTEX_ACQUIRED( addr ) AnnotateRWLockAcquired( __FILE__, __LINE__, reinterpret_cast<void *>(addr), 1 )
+ // must be called before actual release
# define CDS_TSAN_ANNOTATE_MUTEX_RELEASED( addr ) AnnotateRWLockReleased( __FILE__, __LINE__, reinterpret_cast<void *>(addr), 1 )
// provided by TSan
void AnnotateNewMemory(char *f, int l, void * mem, size_t size);
+ void AnnotateRWLockCreate( char *f, int l, void* m )
+ void AnnotateRWLockDestroy( char *f, int l, void* m )
void AnnotateRWLockAcquired( const char *f, int l, void *m, long is_w );
void AnnotateRWLockReleased( const char *f, int l, void *m, long is_w );
}
# define CDS_TSAN_ANNOTATE_NEW_MEMORY( addr, sz )
+# define CDS_TSAN_ANNOTATE_MUTEX_CREATE( addr )
+# define CDS_TSAN_ANNOTATE_MUTEX_DESTROY( addr )
# define CDS_TSAN_ANNOTATE_MUTEX_ACQUIRED( addr )
# define CDS_TSAN_ANNOTATE_MUTEX_RELEASED( addr )
:m_dbgOwnerId( OS::c_NullThreadId )
# endif
{
+ CDS_TSAN_ANNOTATE_MUTEX_CREATE( &m_spin );
m_spin.store( false, atomics::memory_order_relaxed );
}
: m_dbgOwnerId( bLocked ? cds::OS::get_current_thread_id() : cds::OS::c_NullThreadId )
# endif
{
+ CDS_TSAN_ANNOTATE_MUTEX_CREATE( &m_spin );
m_spin.store( bLocked, atomics::memory_order_relaxed );
+# ifdef CDS_THREAD_SANITIZER_ENABLED
+ if ( bLocked )
+ CDS_TSAN_ANNOTATE_MUTEX_ACQUIRED( &m_spin );
+# endif
}
/// Dummy copy constructor
# ifdef CDS_DEBUG
, m_dbgOwnerId( cds::OS::c_NullThreadId )
# endif
- {}
+ {
+ CDS_TSAN_ANNOTATE_MUTEX_CREATE( &m_spin );
+ }
/// Destructor. On debug time it checks whether spin-lock is free
~spin_lock()
{
assert( !m_spin.load( atomics::memory_order_relaxed ));
+ CDS_TSAN_ANNOTATE_MUTEX_DESTROY( &m_spin );
}
/// Check if the spin is locked
assert( m_dbgOwnerId == OS::get_current_thread_id());
CDS_DEBUG_ONLY( m_dbgOwnerId = OS::c_NullThreadId; )
- m_spin.store( false, atomics::memory_order_release );
CDS_TSAN_ANNOTATE_MUTEX_RELEASED( &m_spin );
+ m_spin.store( false, atomics::memory_order_release );
}
};
reentrant_spin_lock() CDS_NOEXCEPT
: m_spin(0)
, m_OwnerId( OS::c_NullThreadId )
- {}
+ {
+ CDS_TSAN_ANNOTATE_MUTEX_CREATE( &m_spin );
+ }
/// Dummy copy constructor
/**
reentrant_spin_lock( const reentrant_spin_lock<Integral, Backoff>& ) CDS_NOEXCEPT
: m_spin(0)
, m_OwnerId( OS::c_NullThreadId )
- {}
+ {
+ CDS_TSAN_ANNOTATE_MUTEX_CREATE( &m_spin );
+ }
- /// Construct object for specified state
+ /// Construct object in specified state
explicit reentrant_spin_lock( bool bLocked )
: m_spin(0)
, m_OwnerId( OS::c_NullThreadId )
{
+ CDS_TSAN_ANNOTATE_MUTEX_CREATE( &m_spin );
if ( bLocked )
lock();
}
m_spin.store( n - 1, atomics::memory_order_relaxed );
else {
free();
- m_spin.store( 0, atomics::memory_order_release );
CDS_TSAN_ANNOTATE_MUTEX_RELEASED( &m_spin );
+ m_spin.store( 0, atomics::memory_order_release );
}
return true;
}