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 cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits