Skip to content

Commit 94a5d68

Browse files
committed
address comments
1 parent 8c5cbf5 commit 94a5d68

File tree

5 files changed

+90
-64
lines changed

5 files changed

+90
-64
lines changed

libcxx/docs/ABIGuarantees.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,10 @@ resulting in an ABI break.
209209
------------------------------------------
210210
This flag changes the implementation of ``atomic::wait()`` and ``atomic::notify_one()/notify_all()`` to use the
211211
native atomic wait/notify operations on platforms that support them based on the size of the atomic type, instead
212-
of the type itself. This means for example that a type with ``sizeof(T) == 4`` on Linux that doesn't have padding bytes would be able to use the underlying platform's atomic wait primitive, which is otherwise only used for ``int32_t``. Since the whole program must use the same implementation for correctness, changing this is an ABI break since libc++ supports linking against TUs that were compiled against older versions of the library.
212+
of the type itself. This means for example that a type with ``sizeof(T) == 4`` on Linux that doesn't have padding
213+
bytes would be able to use the underlying platform's atomic wait primitive, which is otherwise only used for ``int32_t``.
214+
Since the whole program must use the same implementation for correctness, changing this is an ABI break since libc++
215+
supports linking against TUs that were compiled against older versions of the library.
213216

214217

215218
inline namespaces

libcxx/include/__atomic/atomic_sync.h

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ struct __atomic_waitable< _Tp,
6262
#if _LIBCPP_STD_VER >= 20
6363
# if _LIBCPP_HAS_THREADS
6464

65+
# if !_LIBCPP_AVAILABILITY_HAS_NEW_SYNC
66+
6567
// old dylib interface kept for backwards compatibility
6668
_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*) _NOEXCEPT;
6769
_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*) _NOEXCEPT;
@@ -74,37 +76,36 @@ _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
7476
__libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*) _NOEXCEPT;
7577
_LIBCPP_EXPORTED_FROM_ABI void
7678
__libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t) _NOEXCEPT;
79+
# endif // !_LIBCPP_AVAILABILITY_HAS_NEW_SYNC
7780

7881
// new dylib interface
7982

8083
// return the global contention state's current value for the address
8184
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
82-
__atomic_monitor_global(void const volatile* __address) _NOEXCEPT;
85+
__atomic_monitor_global(void const* __address) _NOEXCEPT;
8386

8487
// wait on the global contention state to be changed from the given value for the address
8588
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void
86-
__atomic_wait_global_table(void const volatile* __address, __cxx_contention_t __monitor_value) _NOEXCEPT;
89+
__atomic_wait_global_table(void const* __address, __cxx_contention_t __monitor_value) _NOEXCEPT;
8790

8891
// notify one waiter waiting on the global contention state for the address
89-
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void
90-
__atomic_notify_one_global_table(void const volatile*) _NOEXCEPT;
92+
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_global_table(void const*) _NOEXCEPT;
9193

9294
// notify all waiters waiting on the global contention state for the address
93-
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void
94-
__atomic_notify_all_global_table(void const volatile*) _NOEXCEPT;
95+
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_global_table(void const*) _NOEXCEPT;
9596

9697
// wait on the address directly with the native platform wait
9798
template <std::size_t _Size>
9899
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void
99-
__atomic_wait_native(void const volatile* __address, void const* __old_value) _NOEXCEPT;
100+
__atomic_wait_native(void const* __address, void const* __old_value) _NOEXCEPT;
100101

101102
// notify one waiter waiting on the address directly with the native platform wait
102103
template <std::size_t _Size>
103-
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_native(const volatile void*) _NOEXCEPT;
104+
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_native(const void*) _NOEXCEPT;
104105

105106
// notify all waiters waiting on the address directly with the native platform wait
106107
template <std::size_t _Size>
107-
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_native(const volatile void*) _NOEXCEPT;
108+
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_native(const void*) _NOEXCEPT;
108109

109110
# ifdef __linux__
110111
# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) _APPLY(4)
@@ -160,7 +161,8 @@ struct __atomic_wait_backoff_impl {
160161

161162
_LIBCPP_HIDE_FROM_ABI bool operator()(chrono::nanoseconds __elapsed) const {
162163
if (__elapsed > chrono::microseconds(4)) {
163-
auto __contention_address = __waitable_traits::__atomic_contention_address(__a_);
164+
auto __contention_address = const_cast<const void*>(
165+
static_cast<const volatile void*>(__waitable_traits::__atomic_contention_address(__a_)));
164166

165167
if constexpr (__has_native_atomic_wait<__value_type>) {
166168
auto __atomic_value = __waitable_traits::__atomic_load(__a_, __order_);
@@ -253,25 +255,27 @@ template <class _AtomicWaitable>
253255
_LIBCPP_HIDE_FROM_ABI void __atomic_notify_one(const _AtomicWaitable& __a) {
254256
static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
255257
using __value_type _LIBCPP_NODEBUG = typename __atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__value_type;
258+
using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >;
259+
auto __contention_address =
260+
const_cast<const void*>(static_cast<const volatile void*>(__waitable_traits::__atomic_contention_address(__a)));
256261
if constexpr (__has_native_atomic_wait<__value_type>) {
257-
std::__atomic_notify_one_native<sizeof(__value_type)>(
258-
__atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_contention_address(__a));
262+
std::__atomic_notify_one_native<sizeof(__value_type)>(__contention_address);
259263
} else {
260-
std::__atomic_notify_one_global_table(
261-
__atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_contention_address(__a));
264+
std::__atomic_notify_one_global_table(__contention_address);
262265
}
263266
}
264267

265268
template <class _AtomicWaitable>
266269
_LIBCPP_HIDE_FROM_ABI void __atomic_notify_all(const _AtomicWaitable& __a) {
267270
static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
268271
using __value_type _LIBCPP_NODEBUG = typename __atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__value_type;
272+
using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >;
273+
auto __contention_address =
274+
const_cast<const void*>(static_cast<const volatile void*>(__waitable_traits::__atomic_contention_address(__a)));
269275
if constexpr (__has_native_atomic_wait<__value_type>) {
270-
std::__atomic_notify_all_native<sizeof(__value_type)>(
271-
__atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_contention_address(__a));
276+
std::__atomic_notify_all_native<sizeof(__value_type)>(__contention_address);
272277
} else {
273-
std::__atomic_notify_all_global_table(
274-
__atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_contention_address(__a));
278+
std::__atomic_notify_all_global_table(__contention_address);
275279
}
276280
}
277281

libcxx/include/__atomic/contention_t.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919

2020
_LIBCPP_BEGIN_NAMESPACE_STD
2121

22+
// The original definition of `__cxx_contention_t` seemed a bit arbitrary.
23+
// When we enable the _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE ABI,
24+
// use definitions that are based on what the underlying platform supports
25+
// instead.
2226
#if defined(_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE)
2327

2428
# ifdef __linux__
@@ -29,7 +33,7 @@ using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
2933
using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
3034
# elif defined(_AIX) && !defined(__64BIT__)
3135
using __cxx_contention_t _LIBCPP_NODEBUG = int32_t;
32-
#elif defined(_WIN32)
36+
# elif defined(_WIN32)
3337
using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
3438
# else
3539
using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;

libcxx/lib/abi/CHANGELOG.TXT

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ Version 22.0
2626
Symbol removed: _ZNSt3__118__time_get_storageIcE9__analyzeEcRKNS_5ctypeIcEE
2727
Symbol removed: _ZNSt3__118__time_get_storageIwE4initERKNS_5ctypeIwEE
2828
Symbol removed: _ZNSt3__118__time_get_storageIwE9__analyzeEcRKNS_5ctypeIwEE
29+
30+
* [libc++] Allows any types of size 4 and 8 to use native platform ulock_wait
31+
32+
This patch added symbols for platform wait functions with the size of the type
33+
34+
All platforms
35+
-------------
2936
Symbol added: _ZNSt3__123__atomic_monitor_globalEPVKv
3037
Symbol added: _ZNSt3__126__atomic_wait_global_tableEPVKvi
3138
Symbol added: _ZNSt3__126__atomic_notify_one_nativeILm4EEEvPVKv

0 commit comments

Comments
 (0)