Skip to content

Commit e666b3c

Browse files
committed
[libc++] Add the thread safety annotations unconditionally
1 parent aaa0dd2 commit e666b3c

File tree

6 files changed

+96
-66
lines changed

6 files changed

+96
-66
lines changed

libcxx/.clang-format

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@ AllowShortLambdasOnASingleLine: All
1616
AttributeMacros: [
1717
'_ALIGNAS_TYPE',
1818
'_ALIGNAS',
19+
'_LIBCPP_ACQUIRE_CAPABILITY',
20+
'_LIBCPP_ACQUIRE_SHARED_CAPABILITY',
1921
'_LIBCPP_ALIGNOF',
2022
'_LIBCPP_ALWAYS_INLINE',
23+
'_LIBCPP_CAPABILITY',
2124
'_LIBCPP_CONSTEXPR_SINCE_CXX14',
2225
'_LIBCPP_CONSTEXPR_SINCE_CXX17',
2326
'_LIBCPP_CONSTEXPR_SINCE_CXX20',
@@ -43,10 +46,14 @@ AttributeMacros: [
4346
'_LIBCPP_NO_UNIQUE_ADDRESS',
4447
'_LIBCPP_NOALIAS',
4548
'_LIBCPP_OVERRIDABLE_FUNC_VIS',
49+
'_LIBCPP_RELEASE_CAPABILITY',
50+
'_LIBCPP_REQUIRES_CAPABILITY',
51+
'_LIBCPP_SCOPED_LOCKABLE',
4652
'_LIBCPP_STANDALONE_DEBUG',
4753
'_LIBCPP_TEMPLATE_DATA_VIS',
4854
'_LIBCPP_TEMPLATE_VIS',
49-
'_LIBCPP_THREAD_SAFETY_ANNOTATION',
55+
'_LIBCPP_TRY_ACQUIRE_CAPABILITY',
56+
'_LIBCPP_TRY_ACQUIRE_SHARED_CAPABILITY',
5057
'_LIBCPP_USING_IF_EXISTS',
5158
'_LIBCPP_WEAK',
5259
]

libcxx/include/__config

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -933,23 +933,6 @@ typedef __char32_t char32_t;
933933
# define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
934934
# endif
935935

936-
// Work around the attribute handling in clang. When both __declspec and
937-
// __attribute__ are present, the processing goes awry preventing the definition
938-
// of the types. In MinGW mode, __declspec evaluates to __attribute__, and thus
939-
// combining the two does work.
940-
# if defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) && defined(__clang__) && \
941-
__has_attribute(acquire_capability) && !defined(_MSC_VER)
942-
# define _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS 1
943-
# else
944-
# define _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS 0
945-
# endif
946-
947-
# if _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS
948-
# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) __attribute__((x))
949-
# else
950-
# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x)
951-
# endif
952-
953936
# if _LIBCPP_STD_VER >= 20
954937
# define _LIBCPP_CONSTINIT constinit
955938
# elif __has_attribute(__require_constant_initialization__)
@@ -1196,6 +1179,60 @@ typedef __char32_t char32_t;
11961179
# define _LIBCPP_INIT_PRIORITY_MAX
11971180
# endif
11981181

1182+
# if __has_attribute(__scoped_lockable__)
1183+
# define _LIBCPP_SCOPED_LOCKABLE __attribute__((__scoped_lockable__))
1184+
# else
1185+
# define _LIBCPP_SCOPED_LOCKABLE
1186+
# endif
1187+
1188+
# if __has_attribute(__capability__)
1189+
# define _LIBCPP_CAPABILITY(...) __attribute((__capability__(__VA_ARGS__)))
1190+
# else
1191+
# define _LIBCPP_CAPABILITY(...)
1192+
# endif
1193+
1194+
# if __has_attribute(__acquire_capability__)
1195+
# define _LIBCPP_ACQUIRE_CAPABILITY(...) __attribute__((__acquire_capability__(__VA_ARGS__)))
1196+
# else
1197+
# define _LIBCPP_ACQUIRE_CAPABILITY(...)
1198+
# endif
1199+
1200+
# if __has_attribute(__try_acquire_capability__)
1201+
# define _LIBCPP_TRY_ACQUIRE_CAPABILITY(...) __attribute__((__try_acquire_capability__(__VA_ARGS__)))
1202+
# else
1203+
# define _LIBCPP_TRY_ACQUIRE_CAPABILITY(...)
1204+
# endif
1205+
1206+
# if __has_attribute(__acquire_shared_capability__)
1207+
# define _LIBCPP_ACQUIRE_SHARED_CAPABILITY(...) __attribute__((__acquire_shared_capability__(__VA_ARGS__)))
1208+
# else
1209+
# define _LIBCPP_ACQUIRE_SHARED_CAPABILITY(...)
1210+
# endif
1211+
1212+
# if __has_attribute(__try_acquire_shared_capability__)
1213+
# define _LIBCPP_TRY_ACQUIRE_SHARED_CAPABILITY(...) __attribute__((__try_acquire_shared_capability__(__VA_ARGS__)))
1214+
# else
1215+
# define _LIBCPP_TRY_ACQUIRE_SHARED_CAPABILITY(...)
1216+
# endif
1217+
1218+
# if __has_attribute(__release_capability__)
1219+
# define _LIBCPP_RELEASE_CAPABILITY __attribute__((__release_capability__))
1220+
# else
1221+
# define _LIBCPP_RELEASE_CAPABILITY
1222+
# endif
1223+
1224+
# if __has_attribute(__release_shared_capability__)
1225+
# define _LIBCPP_RELEASE_SHARED_CAPABILITY __attribute__((__release_shared_capability__))
1226+
# else
1227+
# define _LIBCPP_RELEASE_SHARED_CAPABILITY
1228+
# endif
1229+
1230+
# if __has_attribute(__requires_capability__)
1231+
# define _LIBCPP_REQUIRES_CAPABILITY(...) __attribute__((__requires_capability__(__VA_ARGS__)))
1232+
# else
1233+
# define _LIBCPP_REQUIRES_CAPABILITY(...)
1234+
# endif
1235+
11991236
# if __has_attribute(__format__)
12001237
// The attribute uses 1-based indices for ordinary and static member functions.
12011238
// The attribute uses 2-based indices for non-static member functions.

libcxx/include/__mutex/lock_guard.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,22 @@
1919
_LIBCPP_BEGIN_NAMESPACE_STD
2020

2121
template <class _Mutex>
22-
class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) lock_guard {
22+
class _LIBCPP_TEMPLATE_VIS _LIBCPP_SCOPED_LOCKABLE lock_guard {
2323
public:
2424
typedef _Mutex mutex_type;
2525

2626
private:
2727
mutex_type& __m_;
2828

2929
public:
30-
[[__nodiscard__]]
31-
_LIBCPP_HIDE_FROM_ABI explicit lock_guard(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m))
30+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI explicit lock_guard(mutex_type& __m) _LIBCPP_ACQUIRE_CAPABILITY(__m)
3231
: __m_(__m) {
3332
__m_.lock();
3433
}
3534

36-
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI lock_guard(mutex_type& __m, adopt_lock_t)
37-
_LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m))
35+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_REQUIRES_CAPABILITY(__m)
3836
: __m_(__m) {}
39-
_LIBCPP_HIDE_FROM_ABI ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) { __m_.unlock(); }
37+
_LIBCPP_HIDE_FROM_ABI ~lock_guard() _LIBCPP_RELEASE_CAPABILITY { __m_.unlock(); }
4038

4139
lock_guard(lock_guard const&) = delete;
4240
lock_guard& operator=(lock_guard const&) = delete;

libcxx/include/__mutex/mutex.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
_LIBCPP_BEGIN_NAMESPACE_STD
2323

24-
class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex {
24+
class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CAPABILITY("mutex") mutex {
2525
__libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER;
2626

2727
public:
@@ -36,9 +36,9 @@ class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mut
3636
~mutex() _NOEXCEPT;
3737
# endif
3838

39-
void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability());
40-
bool try_lock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true));
41-
void unlock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability());
39+
void lock() _LIBCPP_ACQUIRE_CAPABILITY();
40+
bool try_lock() _NOEXCEPT _LIBCPP_TRY_ACQUIRE_CAPABILITY(true);
41+
void unlock() _NOEXCEPT _LIBCPP_RELEASE_CAPABILITY;
4242

4343
typedef __libcpp_mutex_t* native_handle_type;
4444
_LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }

libcxx/include/mutex

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -435,24 +435,23 @@ public:
435435
};
436436

437437
template <class _Mutex>
438-
class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) scoped_lock<_Mutex> {
438+
class _LIBCPP_TEMPLATE_VIS _LIBCPP_SCOPED_LOCKABLE scoped_lock<_Mutex> {
439439
public:
440440
typedef _Mutex mutex_type;
441441

442442
private:
443443
mutex_type& __m_;
444444

445445
public:
446-
[[nodiscard]]
447-
_LIBCPP_HIDE_FROM_ABI explicit scoped_lock(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m))
446+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit scoped_lock(mutex_type& __m) _LIBCPP_ACQUIRE_CAPABILITY(__m)
448447
: __m_(__m) {
449448
__m_.lock();
450449
}
451450

452-
~scoped_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) { __m_.unlock(); }
451+
_LIBCPP_RELEASE_CAPABILITY _LIBCPP_HIDE_FROM_ABI ~scoped_lock() { __m_.unlock(); }
453452

454-
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit scoped_lock(adopt_lock_t, mutex_type& __m)
455-
_LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m))
453+
[[nodiscard]]
454+
_LIBCPP_HIDE_FROM_ABI explicit scoped_lock(adopt_lock_t, mutex_type& __m) _LIBCPP_REQUIRES_CAPABILITY(__m)
456455
: __m_(__m) {}
457456

458457
scoped_lock(scoped_lock const&) = delete;

libcxx/include/shared_mutex

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ struct _LIBCPP_EXPORTED_FROM_ABI __shared_mutex_base {
180180
};
181181

182182
# if _LIBCPP_STD_VER >= 17
183-
class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_THREAD_SAFETY_ANNOTATION(__capability__("shared_mutex")) shared_mutex {
183+
class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CAPABILITY("shared_mutex") shared_mutex {
184184
__shared_mutex_base __base_;
185185

186186
public:
@@ -191,25 +191,16 @@ public:
191191
shared_mutex& operator=(const shared_mutex&) = delete;
192192

193193
// Exclusive ownership
194-
_LIBCPP_HIDE_FROM_ABI void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_capability__()) {
195-
return __base_.lock();
196-
}
197-
_LIBCPP_HIDE_FROM_ABI bool try_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true)) {
198-
return __base_.try_lock();
199-
}
200-
_LIBCPP_HIDE_FROM_ABI void unlock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_capability__()) {
201-
return __base_.unlock();
202-
}
194+
_LIBCPP_HIDE_FROM_ABI void lock() _LIBCPP_ACQUIRE_CAPABILITY() { return __base_.lock(); }
195+
_LIBCPP_HIDE_FROM_ABI bool try_lock() _LIBCPP_TRY_ACQUIRE_CAPABILITY(true) { return __base_.try_lock(); }
196+
_LIBCPP_HIDE_FROM_ABI void unlock() _LIBCPP_RELEASE_CAPABILITY { return __base_.unlock(); }
203197

204198
// Shared ownership
205-
_LIBCPP_HIDE_FROM_ABI void lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_shared_capability__()) {
206-
return __base_.lock_shared();
207-
}
208-
_LIBCPP_HIDE_FROM_ABI bool try_lock_shared()
209-
_LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true)) {
199+
_LIBCPP_HIDE_FROM_ABI void lock_shared() _LIBCPP_ACQUIRE_SHARED_CAPABILITY() { return __base_.lock_shared(); }
200+
_LIBCPP_HIDE_FROM_ABI bool try_lock_shared() _LIBCPP_ACQUIRE_SHARED_CAPABILITY(true) {
210201
return __base_.try_lock_shared();
211202
}
212-
_LIBCPP_HIDE_FROM_ABI void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_shared_capability__()) {
203+
_LIBCPP_HIDE_FROM_ABI void unlock_shared() _LIBCPP_RELEASE_SHARED_CAPABILITY {
213204
return __base_.unlock_shared();
214205
}
215206

@@ -218,8 +209,7 @@ public:
218209
};
219210
# endif
220211

221-
class _LIBCPP_EXPORTED_FROM_ABI
222-
_LIBCPP_THREAD_SAFETY_ANNOTATION(__capability__("shared_timed_mutex")) shared_timed_mutex {
212+
class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CAPABILITY("shared_timed_mutex") shared_timed_mutex {
223213
__shared_mutex_base __base_;
224214

225215
public:
@@ -230,32 +220,31 @@ public:
230220
shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;
231221

232222
// Exclusive ownership
233-
void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_capability__());
234-
bool try_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true));
223+
void lock() _LIBCPP_ACQUIRE_CAPABILITY();
224+
bool try_lock() _LIBCPP_TRY_ACQUIRE_CAPABILITY(true);
235225
template <class _Rep, class _Period>
236226
_LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time)
237-
_LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true)) {
227+
_LIBCPP_TRY_ACQUIRE_CAPABILITY(true) {
238228
return try_lock_until(chrono::steady_clock::now() + __rel_time);
239229
}
230+
240231
template <class _Clock, class _Duration>
241-
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
242-
try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time)
243-
_LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true));
244-
void unlock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_capability__());
232+
_LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time)
233+
_LIBCPP_TRY_ACQUIRE_CAPABILITY(true);
234+
void unlock() _LIBCPP_RELEASE_CAPABILITY;
245235

246236
// Shared ownership
247-
void lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_shared_capability__());
248-
bool try_lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true));
237+
void lock_shared() _LIBCPP_ACQUIRE_SHARED_CAPABILITY();
238+
bool try_lock_shared() _LIBCPP_TRY_ACQUIRE_SHARED_CAPABILITY(true);
249239
template <class _Rep, class _Period>
250240
_LIBCPP_HIDE_FROM_ABI bool try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time)
251-
_LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true)) {
241+
_LIBCPP_TRY_ACQUIRE_SHARED_CAPABILITY(true) {
252242
return try_lock_shared_until(chrono::steady_clock::now() + __rel_time);
253243
}
254244
template <class _Clock, class _Duration>
255-
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
256-
try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time)
257-
_LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true));
258-
void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_shared_capability__());
245+
_LIBCPP_HIDE_FROM_ABI bool try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time)
246+
_LIBCPP_TRY_ACQUIRE_SHARED_CAPABILITY(true);
247+
void unlock_shared() _LIBCPP_RELEASE_SHARED_CAPABILITY;
259248
};
260249

261250
template <class _Clock, class _Duration>

0 commit comments

Comments
 (0)