]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Tweak TSan annotations for std::atomic<shared_ptr<T>>
authorJonathan Wakely <jwakely@redhat.com>
Thu, 15 Sep 2022 15:57:30 +0000 (16:57 +0100)
committerJonathan Wakely <jwakely@redhat.com>
Thu, 15 Sep 2022 20:04:36 +0000 (21:04 +0100)
Do not use the __tsan_mutex_not_static flag for annotation functions
where it's not a valid flag.  Also use the try_lock and try_lock_failed
flags to more precisely annotate the CAS loop used to acquire a lock.

libstdc++-v3/ChangeLog:

* include/bits/shared_ptr_atomic.h (_GLIBCXX_TSAN_MUTEX_PRE_LOCK):
Replace with ...
(_GLIBCXX_TSAN_MUTEX_TRY_LOCK): ... this, add try_lock flag.
(_GLIBCXX_TSAN_MUTEX_TRY_LOCK_FAILED): New macro using
try_lock_failed flag
(_GLIBCXX_TSAN_MUTEX_POST_LOCK): Rename to ...
(_GLIBCXX_TSAN_MUTEX_LOCKED): ... this.
(_GLIBCXX_TSAN_MUTEX_PRE_UNLOCK): Remove invalid flag.
(_GLIBCXX_TSAN_MUTEX_POST_UNLOCK): Remove invalid flag.
(_Sp_atomic::_Atomic_count::lock): Use new macros.

libstdc++-v3/include/bits/shared_ptr_atomic.h

index 4580807f42ca05d2b50120ccf4347abc3d3f2f95..55d193d4bda7c3c19e4ce1c66bff4ed4bc66e579 100644 (file)
 
 #include <bits/atomic_base.h>
 
+// Annotations for the custom locking in atomic<shared_ptr<T>>.
 #if defined _GLIBCXX_TSAN && __has_include(<sanitizer/tsan_interface.h>)
 #include <sanitizer/tsan_interface.h>
 #define _GLIBCXX_TSAN_MUTEX_DESTROY(X) \
   __tsan_mutex_destroy(X, __tsan_mutex_not_static)
-#define _GLIBCXX_TSAN_MUTEX_PRE_LOCK(X) \
-  __tsan_mutex_pre_lock(X, __tsan_mutex_not_static)
-#define _GLIBCXX_TSAN_MUTEX_POST_LOCK(X) \
+#define _GLIBCXX_TSAN_MUTEX_TRY_LOCK(X) \
+  __tsan_mutex_pre_lock(X, __tsan_mutex_not_static|__tsan_mutex_try_lock)
+#define _GLIBCXX_TSAN_MUTEX_TRY_LOCK_FAILED(X) __tsan_mutex_post_lock(X, \
+    __tsan_mutex_not_static|__tsan_mutex_try_lock_failed, 0)
+#define _GLIBCXX_TSAN_MUTEX_LOCKED(X) \
   __tsan_mutex_post_lock(X, __tsan_mutex_not_static, 0)
-#define _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(X) \
-  __tsan_mutex_pre_unlock(X, __tsan_mutex_not_static)
-#define _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(X) \
-  __tsan_mutex_post_unlock(X, __tsan_mutex_not_static)
+#define _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(X) __tsan_mutex_pre_unlock(X, 0)
+#define _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(X) __tsan_mutex_post_unlock(X, 0)
 #define _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(X) __tsan_mutex_pre_signal(X, 0)
 #define _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(X) __tsan_mutex_post_signal(X, 0)
 #else
 #define _GLIBCXX_TSAN_MUTEX_DESTROY(X)
-#define _GLIBCXX_TSAN_MUTEX_PRE_LOCK(X)
-#define _GLIBCXX_TSAN_MUTEX_POST_LOCK(X)
+#define _GLIBCXX_TSAN_MUTEX_TRY_LOCK(X)
+#define _GLIBCXX_TSAN_MUTEX_TRY_LOCK_FAILED(X)
+#define _GLIBCXX_TSAN_MUTEX_LOCKED(X)
 #define _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(X)
 #define _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(X)
 #define _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(X)
@@ -431,19 +433,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
              __current = _M_val.load(memory_order_relaxed);
            }
 
-         _GLIBCXX_TSAN_MUTEX_PRE_LOCK(&_M_val);
+         _GLIBCXX_TSAN_MUTEX_TRY_LOCK(&_M_val);
 
          while (!_M_val.compare_exchange_strong(__current,
                                                 __current | _S_lock_bit,
                                                 __o,
                                                 memory_order_relaxed))
            {
+             _GLIBCXX_TSAN_MUTEX_TRY_LOCK_FAILED(&_M_val);
 #if __cpp_lib_atomic_wait
              __detail::__thread_relax();
 #endif
              __current = __current & ~_S_lock_bit;
+             _GLIBCXX_TSAN_MUTEX_TRY_LOCK(&_M_val);
            }
-         _GLIBCXX_TSAN_MUTEX_POST_LOCK(&_M_val);
+         _GLIBCXX_TSAN_MUTEX_LOCKED(&_M_val);
          return reinterpret_cast<pointer>(__current);
        }