@@ -56,14 +56,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD
5656
5757#ifdef __linux__
5858
59- // TODO : update
60- static void
61- __libcpp_platform_wait_on_address (__cxx_atomic_contention_t const volatile * __ptr, __cxx_contention_t __val) {
59+ template <std::size_t _Size>
60+ static void __libcpp_platform_wait_on_address (void const volatile * __ptr, void const * __val) {
61+ static_assert (_Size == 4 , " Can only wait on 4 bytes value" );
62+ char buffer[_Size];
63+ std::memcpy (&buffer, const_cast <const void *>(__val), _Size);
6264 static constexpr timespec __timeout = {2 , 0 };
63- _LIBCPP_FUTEX (__ptr, FUTEX_WAIT_PRIVATE, __val , &__timeout, 0 , 0 );
65+ _LIBCPP_FUTEX (__ptr, FUTEX_WAIT_PRIVATE, * reinterpret_cast < __cxx_contention_t const *>(&buffer) , &__timeout, 0 , 0 );
6466}
6567
66- static void __libcpp_platform_wake_by_address (__cxx_atomic_contention_t const volatile * __ptr, bool __notify_one) {
68+ template <std::size_t _Size>
69+ static void __libcpp_platform_wake_by_address (void const volatile * __ptr, bool __notify_one) {
70+ static_assert (_Size == 4 , " Can only wake up on 4 bytes value" );
6771 _LIBCPP_FUTEX (__ptr, FUTEX_WAKE_PRIVATE, __notify_one ? 1 : INT_MAX, 0 , 0 , 0 );
6872}
6973
@@ -100,35 +104,39 @@ static void __libcpp_platform_wake_by_address(void const volatile* __ptr, bool _
100104}
101105
102106#elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8
103- // TODO : update
104107/*
105108 * Since __cxx_contention_t is int64_t even on 32bit FreeBSD
106109 * platforms, we have to use umtx ops that work on the long type, and
107110 * limit its use to architectures where long and int64_t are synonyms.
108111 */
109112
110- static void
111- __libcpp_platform_wait_on_address (__cxx_atomic_contention_t const volatile * __ptr, __cxx_contention_t __val) {
112- _umtx_op (const_cast <__cxx_atomic_contention_t *>(__ptr), UMTX_OP_WAIT, __val, nullptr , nullptr );
113+ template <std::size_t _Size>
114+ static void __libcpp_platform_wait_on_address (void const volatile * __ptr, void const * __val) {
115+ static_assert (_Size == 8 , " Can only wait on 8 bytes value" );
116+ char buffer[_Size];
117+ std::memcpy (&buffer, const_cast <const void *>(__val), _Size);
118+ _umtx_op (const_cast <void *>(__ptr), UMTX_OP_WAIT, *reinterpret_cast <__cxx_contention_t *>(&buffer), nullptr , nullptr );
113119}
114120
115- static void __libcpp_platform_wake_by_address (__cxx_atomic_contention_t const volatile * __ptr, bool __notify_one) {
116- _umtx_op (const_cast <__cxx_atomic_contention_t *>(__ptr), UMTX_OP_WAKE, __notify_one ? 1 : INT_MAX, nullptr , nullptr );
121+ template <std::size_t _Size>
122+ static void __libcpp_platform_wake_by_address (void const volatile * __ptr, bool __notify_one) {
123+ static_assert (_Size == 8 , " Can only wake up on 8 bytes value" );
124+ _umtx_op (const_cast <void *>(__ptr), UMTX_OP_WAKE, __notify_one ? 1 : INT_MAX, nullptr , nullptr );
117125}
118126
119127#else // <- Add other operating systems here
120128
121129// Baseline is just a timed backoff
122- // TODO : update
123130
124- static void
125- __libcpp_platform_wait_on_address (__cxx_atomic_contention_t const volatile * __ptr, __cxx_contention_t __val) {
131+ template <std:: size_t _Size>
132+ static void __libcpp_platform_wait_on_address (void const volatile * __ptr, void const * __val) {
126133 __libcpp_thread_poll_with_backoff (
127- [=]() -> bool { return !__cxx_nonatomic_compare_equal ( __cxx_atomic_load (__ptr, memory_order_relaxed ), __val); },
134+ [=]() -> bool { return !std::memcmp ( const_cast < const void *> (__ptr), __val, _Size ); },
128135 __libcpp_timed_backoff_policy ());
129136}
130137
131- static void __libcpp_platform_wake_by_address (__cxx_atomic_contention_t const volatile *, bool ) {}
138+ template <std::size_t _Size>
139+ static void __libcpp_platform_wake_by_address (void const volatile *, bool ) {}
132140
133141#endif // __linux__
134142
@@ -255,7 +263,12 @@ _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_notify_all_native(void const vola
255263// Instantiation of the templates with supported size
256264#ifdef __linux__
257265
258- // TODO
266+ template _LIBCPP_EXPORTED_FROM_ABI void
267+ __libcpp_atomic_wait_native<4 >(void const volatile * __address, void const * __old_value) noexcept ;
268+
269+ template _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_notify_one_native<4 >(void const volatile * __location) noexcept ;
270+
271+ template _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_notify_all_native<4 >(void const volatile * __location) noexcept ;
259272
260273#elif defined(__APPLE__) && defined(_LIBCPP_USE_ULOCK)
261274
@@ -275,11 +288,21 @@ template _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_notify_all_native<8>(voi
275288
276289#elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8
277290
278- // TODO
291+ template _LIBCPP_EXPORTED_FROM_ABI void
292+ __libcpp_atomic_wait_native<8 >(void const volatile * __address, void const * __old_value) noexcept ;
293+
294+ template _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_notify_one_native<8 >(void const volatile * __location) noexcept ;
295+
296+ template _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_notify_all_native<8 >(void const volatile * __location) noexcept ;
279297
280298#else // <- Add other operating systems here
281299
282- // TODO
300+ template _LIBCPP_EXPORTED_FROM_ABI void
301+ __libcpp_atomic_wait_native<8 >(void const volatile * __address, void const * __old_value) noexcept ;
302+
303+ template _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_notify_one_native<8 >(void const volatile * __location) noexcept ;
304+
305+ template _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_notify_all_native<8 >(void const volatile * __location) noexcept ;
283306
284307#endif // __linux__
285308
0 commit comments