Skip to content

Commit 7784396

Browse files
committed
add support for linux
1 parent 747507a commit 7784396

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
@@ -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

Comments
 (0)