Skip to content

Commit 71bba6f

Browse files
committed
add support for linux
1 parent c5d6769 commit 71bba6f

File tree

1 file changed

+42
-19
lines changed

1 file changed

+42
-19
lines changed

libcxx/src/atomic.cpp

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)