Skip to content

Commit 05c86f8

Browse files
committed
[libc++] Drop support for the C++20 Synchronization Library before C++20
When we initially implemented the C++20 synchronization library, we reluctantly accepted for the implementation to be backported to C++03 upon request from the person who provided the patch. This was when we were only starting to have experience with the issues this can create, so we flinched. Nowadays, we have a much stricter stance about not backporting features to previous standards. We have recently started fixing several bugs (and near bugs) in our implementation of the synchronization library. A recurring theme during these reviews has been how difficult to undertand the current code is, and upon inspection it becomes clear that being able to use a few recent C++ features (in particular lambdas) would help a great deal. The code would still be pretty intricate, but it would be a lot easier to reason about the flow of callbacks through things like __thread_poll_with_backoff. As a result, this patch drops support for the synchronization library before C++20. This makes us more strictly conforming and opens the door to major simplifications, in particular around atomic_wait which was supported all the way to C++03. This change will probably have some impact on downstream users, however since the C++20 synchronization library was added only in LLVM 10 (~3 years ago) and it's quite a niche feature, the set of people trying to use this part of the library before C++20 should be reasonably small.
1 parent a057506 commit 05c86f8

File tree

8 files changed

+73
-59
lines changed

8 files changed

+73
-59
lines changed

libcxx/docs/ReleaseNotes/19.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ Improvements and New Features
5050
Deprecations and Removals
5151
-------------------------
5252

53+
- Support for the C++20 synchronization library (``<barrier>``, ``<latch>``, ``atomic::wait``, etc.) has been
54+
removed in language modes prior to C++20. If you are using these features prior to C++20, you will need to
55+
update to ``-std=c++20``.
56+
5357
- TODO: The ``LIBCXX_EXECUTOR`` CMake variables have been removed.
5458

5559
- TODO: The ``LIBCXX_ENABLE_ASSERTIONS`` CMake variable that was used to enable the safe mode has been deprecated and setting

libcxx/include/__atomic/atomic.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,8 @@ _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong_explicit(
429429
return __o->compare_exchange_strong(*__e, __d, __s, __f);
430430
}
431431

432+
#if _LIBCPP_STD_VER >= 20
433+
432434
// atomic_wait
433435

434436
template <class _Tp>
@@ -481,6 +483,8 @@ _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void atomic_notify_all(atomic<_T
481483
__o->notify_all();
482484
}
483485

486+
#endif // _LIBCPP_STD_VER >= 20
487+
484488
// atomic_fetch_add
485489

486490
template <class _Tp>

libcxx/include/__atomic/atomic_base.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ struct __atomic_base // false
102102
return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
103103
}
104104

105+
#if _LIBCPP_STD_VER >= 20
105106
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const
106107
volatile _NOEXCEPT {
107108
std::__cxx_atomic_wait(std::addressof(__a_), __v, __m);
@@ -122,6 +123,7 @@ struct __atomic_base // false
122123
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT {
123124
std::__cxx_atomic_notify_all(std::addressof(__a_));
124125
}
126+
#endif // _LIBCPP_STD_VER >= 20
125127

126128
#if _LIBCPP_STD_VER >= 20
127129
_LIBCPP_HIDE_FROM_ABI constexpr __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}

libcxx/include/__atomic/atomic_flag.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct atomic_flag {
4747
__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);
4848
}
4949

50+
#if _LIBCPP_STD_VER >= 20
5051
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(bool __v, memory_order __m = memory_order_seq_cst) const
5152
volatile _NOEXCEPT {
5253
__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
@@ -63,6 +64,7 @@ struct atomic_flag {
6364
__cxx_atomic_notify_all(&__a_);
6465
}
6566
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { __cxx_atomic_notify_all(&__a_); }
67+
#endif
6668

6769
#if _LIBCPP_STD_VER >= 20
6870
_LIBCPP_HIDE_FROM_ABI constexpr atomic_flag() _NOEXCEPT : __a_(false) {}
@@ -117,6 +119,7 @@ inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(atomic_flag* __o, m
117119
__o->clear(__m);
118120
}
119121

122+
#if _LIBCPP_STD_VER >= 20
120123
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
121124
atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT {
122125
__o->wait(__v);
@@ -154,6 +157,7 @@ atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT {
154157
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT {
155158
__o->notify_all();
156159
}
160+
#endif // _LIBCPP_STD_VER >= 20
157161

158162
_LIBCPP_END_NAMESPACE_STD
159163

libcxx/include/atomic

Lines changed: 46 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,12 @@ struct atomic
101101
bool compare_exchange_strong(T& expc, T desr,
102102
memory_order m = memory_order_seq_cst) noexcept;
103103
104-
void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept;
105-
void wait(T, memory_order = memory_order::seq_cst) const noexcept;
106-
void notify_one() volatile noexcept;
107-
void notify_one() noexcept;
108-
void notify_all() volatile noexcept;
109-
void notify_all() noexcept;
104+
void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept; // since C++20
105+
void wait(T, memory_order = memory_order::seq_cst) const noexcept; // since C++20
106+
void notify_one() volatile noexcept; // since C++20
107+
void notify_one() noexcept; // since C++20
108+
void notify_all() volatile noexcept; // since C++20
109+
void notify_all() noexcept; // since C++20
110110
};
111111
112112
template <>
@@ -184,12 +184,12 @@ struct atomic<integral>
184184
integral operator^=(integral op) volatile noexcept;
185185
integral operator^=(integral op) noexcept;
186186
187-
void wait(integral, memory_order = memory_order::seq_cst) const volatile noexcept;
188-
void wait(integral, memory_order = memory_order::seq_cst) const noexcept;
189-
void notify_one() volatile noexcept;
190-
void notify_one() noexcept;
191-
void notify_all() volatile noexcept;
192-
void notify_all() noexcept;
187+
void wait(integral, memory_order = memory_order::seq_cst) const volatile noexcept; // since C++20
188+
void wait(integral, memory_order = memory_order::seq_cst) const noexcept; // since C++20
189+
void notify_one() volatile noexcept; // since C++20
190+
void notify_one() noexcept; // since C++20
191+
void notify_all() volatile noexcept; // since C++20
192+
void notify_all() noexcept; // since C++20
193193
};
194194
195195
template <class T>
@@ -254,12 +254,12 @@ struct atomic<T*>
254254
T* operator-=(ptrdiff_t op) volatile noexcept;
255255
T* operator-=(ptrdiff_t op) noexcept;
256256
257-
void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept;
258-
void wait(T*, memory_order = memory_order::seq_cst) const noexcept;
259-
void notify_one() volatile noexcept;
260-
void notify_one() noexcept;
261-
void notify_all() volatile noexcept;
262-
void notify_all() noexcept;
257+
void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept; // since C++20
258+
void wait(T*, memory_order = memory_order::seq_cst) const noexcept; // since C++20
259+
void notify_one() volatile noexcept; // since C++20
260+
void notify_one() noexcept; // since C++20
261+
void notify_all() volatile noexcept; // since C++20
262+
void notify_all() noexcept; // since C++20
263263
};
264264
265265
template<>
@@ -321,12 +321,12 @@ struct atomic<floating-point-type> { // since C++20
321321
floating-point-type operator-=(floating-point-type) volatile noexcept;
322322
floating-point-type operator-=(floating-point-type) noexcept;
323323
324-
void wait(floating-point-type, memory_order = memory_order::seq_cst) const volatile noexcept;
325-
void wait(floating-point-type, memory_order = memory_order::seq_cst) const noexcept;
326-
void notify_one() volatile noexcept;
327-
void notify_one() noexcept;
328-
void notify_all() volatile noexcept;
329-
void notify_all() noexcept;
324+
void wait(floating-point-type, memory_order = memory_order::seq_cst) const volatile noexcept; // since C++20
325+
void wait(floating-point-type, memory_order = memory_order::seq_cst) const noexcept; // since C++20
326+
void notify_one() volatile noexcept; // since C++20
327+
void notify_one() noexcept; // since C++20
328+
void notify_all() volatile noexcept; // since C++20
329+
void notify_all() noexcept; // since C++20
330330
};
331331
332332
// [atomics.nonmembers], non-member functions
@@ -443,23 +443,23 @@ template<class T>
443443
memory_order) noexcept;
444444
445445
template<class T>
446-
void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type) noexcept;
446+
void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type) noexcept; // since C++20
447447
template<class T>
448-
void atomic_wait(const atomic<T>*, atomic<T>::value_type) noexcept;
448+
void atomic_wait(const atomic<T>*, atomic<T>::value_type) noexcept; // since C++20
449449
template<class T>
450-
void atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type,
450+
void atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type, // since C++20
451451
memory_order) noexcept;
452452
template<class T>
453-
void atomic_wait_explicit(const atomic<T>*, atomic<T>::value_type,
453+
void atomic_wait_explicit(const atomic<T>*, atomic<T>::value_type, // since C++20
454454
memory_order) noexcept;
455455
template<class T>
456-
void atomic_notify_one(volatile atomic<T>*) noexcept;
456+
void atomic_notify_one(volatile atomic<T>*) noexcept; // since C++20
457457
template<class T>
458-
void atomic_notify_one(atomic<T>*) noexcept;
458+
void atomic_notify_one(atomic<T>*) noexcept; // since C++20
459459
template<class T>
460-
void atomic_notify_all(volatile atomic<T>*) noexcept;
460+
void atomic_notify_all(volatile atomic<T>*) noexcept; // since C++20
461461
template<class T>
462-
void atomic_notify_all(atomic<T>*) noexcept;
462+
void atomic_notify_all(atomic<T>*) noexcept; // since C++20
463463
464464
// Atomics for standard typedef types
465465
@@ -534,12 +534,12 @@ typedef struct atomic_flag
534534
void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
535535
void clear(memory_order m = memory_order_seq_cst) noexcept;
536536
537-
void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept;
538-
void wait(bool, memory_order = memory_order::seq_cst) const noexcept;
539-
void notify_one() volatile noexcept;
540-
void notify_one() noexcept;
541-
void notify_all() volatile noexcept;
542-
void notify_all() noexcept;
537+
void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept; // since C++20
538+
void wait(bool, memory_order = memory_order::seq_cst) const noexcept; // since C++20
539+
void notify_one() volatile noexcept; // since C++20
540+
void notify_one() noexcept; // since C++20
541+
void notify_all() volatile noexcept; // since C++20
542+
void notify_all() noexcept; // since C++20
543543
} atomic_flag;
544544
545545
bool atomic_flag_test(volatile atomic_flag* obj) noexcept;
@@ -557,14 +557,14 @@ void atomic_flag_clear(atomic_flag* obj) noexcept;
557557
void atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
558558
void atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
559559
560-
void atomic_wait(const volatile atomic_flag* obj, T old) noexcept;
561-
void atomic_wait(const atomic_flag* obj, T old) noexcept;
562-
void atomic_wait_explicit(const volatile atomic_flag* obj, T old, memory_order m) noexcept;
563-
void atomic_wait_explicit(const atomic_flag* obj, T old, memory_order m) noexcept;
564-
void atomic_one(volatile atomic_flag* obj) noexcept;
565-
void atomic_one(atomic_flag* obj) noexcept;
566-
void atomic_all(volatile atomic_flag* obj) noexcept;
567-
void atomic_all(atomic_flag* obj) noexcept;
560+
void atomic_wait(const volatile atomic_flag* obj, T old) noexcept; // since C++20
561+
void atomic_wait(const atomic_flag* obj, T old) noexcept; // since C++20
562+
void atomic_wait_explicit(const volatile atomic_flag* obj, T old, memory_order m) noexcept; // since C++20
563+
void atomic_wait_explicit(const atomic_flag* obj, T old, memory_order m) noexcept; // since C++20
564+
void atomic_one(volatile atomic_flag* obj) noexcept; // since C++20
565+
void atomic_one(atomic_flag* obj) noexcept; // since C++20
566+
void atomic_all(volatile atomic_flag* obj) noexcept; // since C++20
567+
void atomic_all(atomic_flag* obj) noexcept; // since C++20
568568
569569
// fences
570570

libcxx/include/barrier

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace std
1717
{
1818
1919
template<class CompletionFunction = see below>
20-
class barrier
20+
class barrier // since C++20
2121
{
2222
public:
2323
using arrival_token = see below;
@@ -71,7 +71,7 @@ namespace std
7171
_LIBCPP_PUSH_MACROS
7272
#include <__undef_macros>
7373

74-
#if _LIBCPP_STD_VER >= 14
74+
#if _LIBCPP_STD_VER >= 20
7575

7676
_LIBCPP_BEGIN_NAMESPACE_STD
7777

@@ -293,7 +293,7 @@ public:
293293

294294
_LIBCPP_END_NAMESPACE_STD
295295

296-
#endif // _LIBCPP_STD_VER >= 14
296+
#endif // _LIBCPP_STD_VER >= 20
297297

298298
_LIBCPP_POP_MACROS
299299

@@ -306,4 +306,4 @@ _LIBCPP_POP_MACROS
306306
# include <variant>
307307
#endif
308308

309-
#endif //_LIBCPP_BARRIER
309+
#endif // !_LIBCPP_BARRIER

libcxx/include/latch

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
namespace std
1717
{
1818
19-
class latch
19+
class latch // since C++20
2020
{
2121
public:
2222
static constexpr ptrdiff_t max() noexcept;
@@ -62,7 +62,7 @@ namespace std
6262
_LIBCPP_PUSH_MACROS
6363
#include <__undef_macros>
6464

65-
#if _LIBCPP_STD_VER >= 14
65+
#if _LIBCPP_STD_VER >= 20
6666

6767
_LIBCPP_BEGIN_NAMESPACE_STD
6868

@@ -112,12 +112,12 @@ public:
112112

113113
_LIBCPP_END_NAMESPACE_STD
114114

115-
#endif // _LIBCPP_STD_VER >= 14
115+
#endif // _LIBCPP_STD_VER >= 20
116116

117117
_LIBCPP_POP_MACROS
118118

119119
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
120120
# include <atomic>
121121
#endif
122122

123-
#endif //_LIBCPP_LATCH
123+
#endif // !_LIBCPP_LATCH

libcxx/include/semaphore

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
namespace std {
1717
1818
template<ptrdiff_t least_max_value = implementation-defined>
19-
class counting_semaphore
19+
class counting_semaphore // since C++20
2020
{
2121
public:
2222
static constexpr ptrdiff_t max() noexcept;
@@ -39,7 +39,7 @@ private:
3939
ptrdiff_t counter; // exposition only
4040
};
4141
42-
using binary_semaphore = counting_semaphore<1>;
42+
using binary_semaphore = counting_semaphore<1>; // since C++20
4343
4444
}
4545
@@ -72,7 +72,7 @@ using binary_semaphore = counting_semaphore<1>;
7272
_LIBCPP_PUSH_MACROS
7373
#include <__undef_macros>
7474

75-
#if _LIBCPP_STD_VER >= 14
75+
#if _LIBCPP_STD_VER >= 20
7676

7777
_LIBCPP_BEGIN_NAMESPACE_STD
7878

@@ -186,12 +186,12 @@ using binary_semaphore = counting_semaphore<1>;
186186

187187
_LIBCPP_END_NAMESPACE_STD
188188

189-
#endif // _LIBCPP_STD_VER >= 14
189+
#endif // _LIBCPP_STD_VER >= 20
190190

191191
_LIBCPP_POP_MACROS
192192

193193
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
194194
# include <atomic>
195195
#endif
196196

197-
#endif //_LIBCPP_SEMAPHORE
197+
#endif // !_LIBCPP_SEMAPHORE

0 commit comments

Comments
 (0)