jamesr updated this revision to Diff 41581.
jamesr added a comment.

Updates the macros to avoid defining anything if _LIBCPP_THREAD_ANNOTATION is 
already defined and to define _LIBCPP_THREAD_ANNOTATION to nothing if __clang__ 
is not set, __has_attribute(acquire_capability) is not set, or 
_LIBCPP_HAS_NO_THREAD_ANNOTATIONS is set.

It turns out there's not a clean feature guard for the thread safety 
annotations (i.e. no __has_feature() guard).  The annotations were added over 
time to clang.  I'm not sure at which point the feature was considered stable 
enough for general use.  Looking at clang's history the most recently added 
annotation out of the ones this patch uses is acquire_capability which was 
added in this commit: https://llvm.org/svn/llvm-project/cfe/trunk@201890, so 
I'm testing for that annotation to test for support for the feature as a whole. 
 It's quite possible that there are revisions of clang after the annotation 
support was added that contain bugs that make the annotations not very useful 
but the fix for any users trying to use such versions of clang is easy - just 
avoid passing -Wthread-safety to these versions of clang.


http://reviews.llvm.org/D14731

Files:
  include/__config
  include/__mutex_base

Index: include/__mutex_base
===================================================================
--- include/__mutex_base
+++ include/__mutex_base
@@ -26,7 +26,15 @@
 
 #ifndef _LIBCPP_HAS_NO_THREADS
 
-class _LIBCPP_TYPE_VIS mutex
+#ifndef _LIBCPP_THREAD_ANNOTATION
+#  ifndef _LIBCPP_HAS_NO_THREAD_ANNOTATIONS
+#    define _LIBCPP_THREAD_ANNOTATION(x) __attribute__((x))
+#  else
+#    define _LIBCPP_THREAD_ANNOTATION(x)
+#  endif
+#endif  // _LIBCPP_THREAD_ANNOTATION
+
+class _LIBCPP_TYPE_VIS _LIBCPP_THREAD_ANNOTATION(capability("mutex")) mutex
 {
     pthread_mutex_t __m_;
 
@@ -44,9 +52,9 @@
     mutex& operator=(const mutex&);// = delete;
 
 public:
-    void lock();
-    bool try_lock() _NOEXCEPT;
-    void unlock() _NOEXCEPT;
+    void lock() _LIBCPP_THREAD_ANNOTATION(acquire_capability());
+    bool try_lock() _NOEXCEPT 
_LIBCPP_THREAD_ANNOTATION(try_acquire_capability(true));
+    void unlock() _NOEXCEPT _LIBCPP_THREAD_ANNOTATION(release_capability());
 
     typedef pthread_mutex_t* native_handle_type;
     _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return 
&__m_;}
@@ -71,7 +79,7 @@
 #endif
 
 template <class _Mutex>
-class _LIBCPP_TYPE_VIS_ONLY lock_guard
+class _LIBCPP_TYPE_VIS_ONLY _LIBCPP_THREAD_ANNOTATION(scoped_lockable) 
lock_guard
 {
 public:
     typedef _Mutex mutex_type;
@@ -81,13 +89,13 @@
 public:
 
     _LIBCPP_INLINE_VISIBILITY
-    explicit lock_guard(mutex_type& __m)
+    explicit lock_guard(mutex_type& __m) 
_LIBCPP_THREAD_ANNOTATION(acquire_capability(__m))
         : __m_(__m) {__m_.lock();}
     _LIBCPP_INLINE_VISIBILITY
-    lock_guard(mutex_type& __m, adopt_lock_t)
+    lock_guard(mutex_type& __m, adopt_lock_t) 
_LIBCPP_THREAD_ANNOTATION(requires_capability(__m))
         : __m_(__m) {}
     _LIBCPP_INLINE_VISIBILITY
-    ~lock_guard() {__m_.unlock();}
+    ~lock_guard() _LIBCPP_THREAD_ANNOTATION(release_capability()) 
{__m_.unlock();}
 
 private:
     lock_guard(lock_guard const&);// = delete;
Index: include/__config
===================================================================
--- include/__config
+++ include/__config
@@ -825,6 +825,11 @@
 #define _LIBCPP_HAS_NO_ATOMIC_HEADER
 #endif
 
+#if (!defined(_LIBCPP_HAS_NO_THREAD_ANNOTATIONS) && (!defined(__clang__) \
+      || !__has_attribute(acquire_capability)))
+#define _LIBCPP_HAS_NO_THREAD_ANNOTATIONS
+#endif
+
 #endif // __cplusplus
 
 #endif // _LIBCPP_CONFIG


Index: include/__mutex_base
===================================================================
--- include/__mutex_base
+++ include/__mutex_base
@@ -26,7 +26,15 @@
 
 #ifndef _LIBCPP_HAS_NO_THREADS
 
-class _LIBCPP_TYPE_VIS mutex
+#ifndef _LIBCPP_THREAD_ANNOTATION
+#  ifndef _LIBCPP_HAS_NO_THREAD_ANNOTATIONS
+#    define _LIBCPP_THREAD_ANNOTATION(x) __attribute__((x))
+#  else
+#    define _LIBCPP_THREAD_ANNOTATION(x)
+#  endif
+#endif  // _LIBCPP_THREAD_ANNOTATION
+
+class _LIBCPP_TYPE_VIS _LIBCPP_THREAD_ANNOTATION(capability("mutex")) mutex
 {
     pthread_mutex_t __m_;
 
@@ -44,9 +52,9 @@
     mutex& operator=(const mutex&);// = delete;
 
 public:
-    void lock();
-    bool try_lock() _NOEXCEPT;
-    void unlock() _NOEXCEPT;
+    void lock() _LIBCPP_THREAD_ANNOTATION(acquire_capability());
+    bool try_lock() _NOEXCEPT _LIBCPP_THREAD_ANNOTATION(try_acquire_capability(true));
+    void unlock() _NOEXCEPT _LIBCPP_THREAD_ANNOTATION(release_capability());
 
     typedef pthread_mutex_t* native_handle_type;
     _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;}
@@ -71,7 +79,7 @@
 #endif
 
 template <class _Mutex>
-class _LIBCPP_TYPE_VIS_ONLY lock_guard
+class _LIBCPP_TYPE_VIS_ONLY _LIBCPP_THREAD_ANNOTATION(scoped_lockable) lock_guard
 {
 public:
     typedef _Mutex mutex_type;
@@ -81,13 +89,13 @@
 public:
 
     _LIBCPP_INLINE_VISIBILITY
-    explicit lock_guard(mutex_type& __m)
+    explicit lock_guard(mutex_type& __m) _LIBCPP_THREAD_ANNOTATION(acquire_capability(__m))
         : __m_(__m) {__m_.lock();}
     _LIBCPP_INLINE_VISIBILITY
-    lock_guard(mutex_type& __m, adopt_lock_t)
+    lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_THREAD_ANNOTATION(requires_capability(__m))
         : __m_(__m) {}
     _LIBCPP_INLINE_VISIBILITY
-    ~lock_guard() {__m_.unlock();}
+    ~lock_guard() _LIBCPP_THREAD_ANNOTATION(release_capability()) {__m_.unlock();}
 
 private:
     lock_guard(lock_guard const&);// = delete;
Index: include/__config
===================================================================
--- include/__config
+++ include/__config
@@ -825,6 +825,11 @@
 #define _LIBCPP_HAS_NO_ATOMIC_HEADER
 #endif
 
+#if (!defined(_LIBCPP_HAS_NO_THREAD_ANNOTATIONS) && (!defined(__clang__) \
+      || !__has_attribute(acquire_capability)))
+#define _LIBCPP_HAS_NO_THREAD_ANNOTATIONS
+#endif
+
 #endif // __cplusplus
 
 #endif // _LIBCPP_CONFIG
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to