dim updated this revision to Diff 84451.
dim added a comment.
Something like this might work, maybe. (I haven't yet run the full test suite,
as that takes quite a while on my machines.)
I did not re-use the `_LIBCPP_THREAD_SAFETY_ANNOTATION` macro from
`__mutex_base`, since that is included *after* this file, and it is only
enabled when the user defines `_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS`. The
`_LIBCPP_THREAD_SAFETY_ATTRIBUTE` macro is defined iff clang supports any of
the thread safety stuff.
Note that I had to add a capability attribute to the `__libcpp_mutex` types,
otherwise this would not work.
Also, I had to place the thread safety attributes *after* the function
declarations, since otherwise the compiler complains that it does not know the
parameter name `__m`.
Furthermore, I am still not sure whether the `true` value for the
`try_acquire_capability` attribute it correct. If I understand the
documentation correctly, `true` means that the function only succeeds when
trying the lock actually acquires it, and it fails when the lock was already
acquired.
https://reviews.llvm.org/D28520
Files:
include/__threading_support
Index: include/__threading_support
===================================================================
--- include/__threading_support
+++ include/__threading_support
@@ -40,14 +40,22 @@
#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
#endif
+#if defined(__clang__) && __has_attribute(acquire_capability))
+#define _LIBCPP_THREAD_SAFETY_ATTRIBUTE(x) __attribute__((x))
+#else
+#define _LIBCPP_THREAD_SAFETY_ATTRIBUTE(x) __attribute__((x))
+#endif
+
_LIBCPP_BEGIN_NAMESPACE_STD
#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
// Mutex
-typedef pthread_mutex_t __libcpp_mutex_t;
+typedef pthread_mutex_t __libcpp_mutex_t
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(capability("mutex"));
#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
-typedef pthread_mutex_t __libcpp_recursive_mutex_t;
+typedef pthread_mutex_t __libcpp_recursive_mutex_t
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(capability("mutex"));
// Condition Variable
typedef pthread_cond_t __libcpp_condvar_t;
@@ -99,25 +107,31 @@
int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
+int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(acquire_capability(*__m));
_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
+int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(try_acquire_capability(true, *__m));
_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
+int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(release_capability(*__m));
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_mutex_lock(__libcpp_mutex_t *__m);
+int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(acquire_capability(*__m));
_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
+int __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(try_acquire_capability(true, *__m));
_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
+int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(release_capability(*__m));
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
@@ -130,11 +144,13 @@
int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
+int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m)
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(requires_capability(*__m));
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
- timespec *__ts);
+ timespec *__ts)
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(requires_capability(*__m));
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
Index: include/__threading_support
===================================================================
--- include/__threading_support
+++ include/__threading_support
@@ -40,14 +40,22 @@
#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
#endif
+#if defined(__clang__) && __has_attribute(acquire_capability))
+#define _LIBCPP_THREAD_SAFETY_ATTRIBUTE(x) __attribute__((x))
+#else
+#define _LIBCPP_THREAD_SAFETY_ATTRIBUTE(x) __attribute__((x))
+#endif
+
_LIBCPP_BEGIN_NAMESPACE_STD
#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
// Mutex
-typedef pthread_mutex_t __libcpp_mutex_t;
+typedef pthread_mutex_t __libcpp_mutex_t
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(capability("mutex"));
#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
-typedef pthread_mutex_t __libcpp_recursive_mutex_t;
+typedef pthread_mutex_t __libcpp_recursive_mutex_t
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(capability("mutex"));
// Condition Variable
typedef pthread_cond_t __libcpp_condvar_t;
@@ -99,25 +107,31 @@
int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
+int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(acquire_capability(*__m));
_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
+int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(try_acquire_capability(true, *__m));
_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
+int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(release_capability(*__m));
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_mutex_lock(__libcpp_mutex_t *__m);
+int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(acquire_capability(*__m));
_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
+int __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(try_acquire_capability(true, *__m));
_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
+int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(release_capability(*__m));
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
@@ -130,11 +144,13 @@
int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
+int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m)
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(requires_capability(*__m));
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
- timespec *__ts);
+ timespec *__ts)
+_LIBCPP_THREAD_SAFETY_ATTRIBUTE(requires_capability(*__m));
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits