@@ -61,14 +61,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD
6161
6262#ifdef __linux__
6363
64- // TODO : update
65- static void
66- __libcpp_platform_wait_on_address (__cxx_atomic_contention_t const volatile * __ptr, __cxx_contention_t __val) {
64+ template <std::size_t _Size>
65+ static void __libcpp_platform_wait_on_address (void const volatile * __ptr, void const * __val) {
66+ static_assert (_Size == 4 , " Can only wait on 4 bytes value" );
67+ char buffer[_Size];
68+ std::memcpy (&buffer, const_cast <const void *>(__val), _Size);
6769 static constexpr timespec __timeout = {2 , 0 };
68- _LIBCPP_FUTEX (__ptr, FUTEX_WAIT_PRIVATE, __val , &__timeout, 0 , 0 );
70+ _LIBCPP_FUTEX (__ptr, FUTEX_WAIT_PRIVATE, * reinterpret_cast < __cxx_contention_t const *>(&buffer) , &__timeout, 0 , 0 );
6971}
7072
71- static void __libcpp_platform_wake_by_address (__cxx_atomic_contention_t const volatile * __ptr, bool __notify_one) {
73+ template <std::size_t _Size>
74+ static void __libcpp_platform_wake_by_address (void const volatile * __ptr, bool __notify_one) {
75+ static_assert (_Size == 4 , " Can only wake up on 4 bytes value" );
7276 _LIBCPP_FUTEX (__ptr, FUTEX_WAKE_PRIVATE, __notify_one ? 1 : INT_MAX, 0 , 0 , 0 );
7377}
7478
@@ -105,20 +109,24 @@ static void __libcpp_platform_wake_by_address(void const volatile* __ptr, bool _
105109}
106110
107111#elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8
108- // TODO : update
109112/*
110113 * Since __cxx_contention_t is int64_t even on 32bit FreeBSD
111114 * platforms, we have to use umtx ops that work on the long type, and
112115 * limit its use to architectures where long and int64_t are synonyms.
113116 */
114117
115- static void
116- __libcpp_platform_wait_on_address (__cxx_atomic_contention_t const volatile * __ptr, __cxx_contention_t __val) {
117- _umtx_op (const_cast <__cxx_atomic_contention_t *>(__ptr), UMTX_OP_WAIT, __val, nullptr , nullptr );
118+ template <std::size_t _Size>
119+ static void __libcpp_platform_wait_on_address (void const volatile * __ptr, void const * __val) {
120+ static_assert (_Size == 8 , " Can only wait on 8 bytes value" );
121+ char buffer[_Size];
122+ std::memcpy (&buffer, const_cast <const void *>(__val), _Size);
123+ _umtx_op (const_cast <void *>(__ptr), UMTX_OP_WAIT, *reinterpret_cast <__cxx_contention_t *>(&buffer), nullptr , nullptr );
118124}
119125
120- static void __libcpp_platform_wake_by_address (__cxx_atomic_contention_t const volatile * __ptr, bool __notify_one) {
121- _umtx_op (const_cast <__cxx_atomic_contention_t *>(__ptr), UMTX_OP_WAKE, __notify_one ? 1 : INT_MAX, nullptr , nullptr );
126+ template <std::size_t _Size>
127+ static void __libcpp_platform_wake_by_address (void const volatile * __ptr, bool __notify_one) {
128+ static_assert (_Size == 8 , " Can only wake up on 8 bytes value" );
129+ _umtx_op (const_cast <void *>(__ptr), UMTX_OP_WAKE, __notify_one ? 1 : INT_MAX, nullptr , nullptr );
122130}
123131
124132#elif defined(_WIN32)
@@ -188,16 +196,16 @@ static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const vo
188196#else // <- Add other operating systems here
189197
190198// Baseline is just a timed backoff
191- // TODO : update
192199
193- static void
194- __libcpp_platform_wait_on_address (__cxx_atomic_contention_t const volatile * __ptr, __cxx_contention_t __val) {
200+ template <std:: size_t _Size>
201+ static void __libcpp_platform_wait_on_address (void const volatile * __ptr, void const * __val) {
195202 __libcpp_thread_poll_with_backoff (
196- [=]() -> bool { return !__cxx_nonatomic_compare_equal ( __cxx_atomic_load (__ptr, memory_order_relaxed ), __val); },
203+ [=]() -> bool { return !std::memcmp ( const_cast < const void *> (__ptr), __val, _Size ); },
197204 __libcpp_timed_backoff_policy ());
198205}
199206
200- static void __libcpp_platform_wake_by_address (__cxx_atomic_contention_t const volatile *, bool ) {}
207+ template <std::size_t _Size>
208+ static void __libcpp_platform_wake_by_address (void const volatile *, bool ) {}
201209
202210#endif // __linux__
203211
@@ -324,7 +332,12 @@ _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_notify_all_native(void const vola
324332// Instantiation of the templates with supported size
325333#ifdef __linux__
326334
327- // TODO
335+ template _LIBCPP_EXPORTED_FROM_ABI void
336+ __libcpp_atomic_wait_native<4 >(void const volatile * __address, void const * __old_value) noexcept ;
337+
338+ template _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_notify_one_native<4 >(void const volatile * __location) noexcept ;
339+
340+ template _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_notify_all_native<4 >(void const volatile * __location) noexcept ;
328341
329342#elif defined(__APPLE__) && defined(_LIBCPP_USE_ULOCK)
330343
@@ -344,11 +357,21 @@ template _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_notify_all_native<8>(voi
344357
345358#elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8
346359
347- // TODO
360+ template _LIBCPP_EXPORTED_FROM_ABI void
361+ __libcpp_atomic_wait_native<8 >(void const volatile * __address, void const * __old_value) noexcept ;
362+
363+ template _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_notify_one_native<8 >(void const volatile * __location) noexcept ;
364+
365+ template _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_notify_all_native<8 >(void const volatile * __location) noexcept ;
348366
349367#else // <- Add other operating systems here
350368
351- // TODO
369+ template _LIBCPP_EXPORTED_FROM_ABI void
370+ __libcpp_atomic_wait_native<8 >(void const volatile * __address, void const * __old_value) noexcept ;
371+
372+ template _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_notify_one_native<8 >(void const volatile * __location) noexcept ;
373+
374+ template _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_notify_all_native<8 >(void const volatile * __location) noexcept ;
352375
353376#endif // __linux__
354377
0 commit comments