[libcxx-commits] [libcxx] [libc++] Fix FreeBSD atomic timed wait system call (PR #180400)
via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Feb 13 11:25:41 PST 2026
https://github.com/huixie90 updated https://github.com/llvm/llvm-project/pull/180400
>From eb52046ddd086225c8523b4f3a3d0927c970cdf1 Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sun, 8 Feb 2026 10:02:01 +0000
Subject: [PATCH 1/5] [libc++] FreeBSD use fallback for atomic timed wait
---
libcxx/src/atomic.cpp | 15 ++++-----------
1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp
index 9f2e0403f2318..8ef78915daa08 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -149,17 +149,10 @@ static void __platform_wait_on_address(void const* __ptr, void const* __val, May
if constexpr (is_same_v<MaybeTimeout, NoTimeout>) {
_umtx_op(const_cast<void*>(__ptr), UMTX_OP_WAIT, *reinterpret_cast<__cxx_contention_t*>(&buffer), nullptr, nullptr);
} else {
- _umtx_time ut;
- ut._timeout.tv_sec = maybe_timeout_ns / 1'000'000'000;
- ut._timeout.tv_nsec = maybe_timeout_ns % 1'000'000'000;
- ut._flags = 0; // Relative time (not absolute)
- ut._clockid = CLOCK_MONOTONIC; // Use monotonic clock
-
- _umtx_op(const_cast<void*>(__ptr),
- UMTX_OP_WAIT,
- *reinterpret_cast<__cxx_contention_t*>(&buffer),
- reinterpret_cast<void*>(sizeof(ut)), // Pass size as uaddr
- &ut); // Pass _umtx_time structure as uaddr2
+ __libcpp_thread_poll_with_backoff(
+ [=]() -> bool { return std::memcmp(const_cast<const void*>(__ptr), __val, _Size) != 0; },
+ __libcpp_timed_backoff_policy(),
+ std::chrono::nanoseconds(__timeout_ns));
}
}
>From 60d18328b7ad7f20bd5d09597928fbf8af566bf5 Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Wed, 11 Feb 2026 12:51:57 +0000
Subject: [PATCH 2/5] fix
---
libcxx/src/atomic.cpp | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp
index 8ef78915daa08..6b6c317bf095a 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -149,10 +149,15 @@ static void __platform_wait_on_address(void const* __ptr, void const* __val, May
if constexpr (is_same_v<MaybeTimeout, NoTimeout>) {
_umtx_op(const_cast<void*>(__ptr), UMTX_OP_WAIT, *reinterpret_cast<__cxx_contention_t*>(&buffer), nullptr, nullptr);
} else {
- __libcpp_thread_poll_with_backoff(
- [=]() -> bool { return std::memcmp(const_cast<const void*>(__ptr), __val, _Size) != 0; },
- __libcpp_timed_backoff_policy(),
- std::chrono::nanoseconds(__timeout_ns));
+ timespec timeout{};
+ timeout.tv_sec = __timeout_ns / 1'000'000'000;
+ timeout.tv_nsec = __timeout_ns % 1'000'000'000;
+
+ _umtx_op(const_cast<void*>(__ptr),
+ UMTX_OP_WAIT,
+ *reinterpret_cast<__cxx_contention_t*>(&buffer),
+ static_cast<void*>(static_cast<uintptr_t>(sizeof(timeout))),
+ &timeout);
}
}
>From c7a2ad2001c23f46ec52e15bc16efcd464f4be32 Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Wed, 11 Feb 2026 14:16:04 +0000
Subject: [PATCH 3/5] review
---
libcxx/src/atomic.cpp | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp
index 6b6c317bf095a..18fa90b857cab 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -144,10 +144,13 @@ static void __platform_wake_by_address(void const* __ptr, bool __notify_one) {
template <std::size_t _Size, class MaybeTimeout>
static void __platform_wait_on_address(void const* __ptr, void const* __val, MaybeTimeout maybe_timeout_ns) {
static_assert(_Size == 8, "Can only wait on 8 bytes value");
- alignas(__cxx_contention_t) char buffer[_Size];
- std::memcpy(&buffer, const_cast<const void*>(__val), _Size);
+ // At the moment, FreeBSD is stuck on stable ABI, which only supports platform wait with __cxx_contention_t
+ // It is safe to reinterpret_cast the val as it is ever going to be passed a __cxx_contention_t under this ABI
+ // If in the future FreeBSD decides to experiment unstable ABI to support more types, this cast will no longer be
+ // safe.
+ __cxx_contention_t value = *reinterpret_cast<const __cxx_contention_t*>(__val);
if constexpr (is_same_v<MaybeTimeout, NoTimeout>) {
- _umtx_op(const_cast<void*>(__ptr), UMTX_OP_WAIT, *reinterpret_cast<__cxx_contention_t*>(&buffer), nullptr, nullptr);
+ _umtx_op(const_cast<void*>(__ptr), UMTX_OP_WAIT, value, nullptr, nullptr);
} else {
timespec timeout{};
timeout.tv_sec = __timeout_ns / 1'000'000'000;
@@ -155,7 +158,7 @@ static void __platform_wait_on_address(void const* __ptr, void const* __val, May
_umtx_op(const_cast<void*>(__ptr),
UMTX_OP_WAIT,
- *reinterpret_cast<__cxx_contention_t*>(&buffer),
+ value,
static_cast<void*>(static_cast<uintptr_t>(sizeof(timeout))),
&timeout);
}
>From 628d9b9a542d29b9a1d8e3f7164e102f7ec5c624 Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Fri, 13 Feb 2026 08:39:51 +0000
Subject: [PATCH 4/5] rebase and fix ci
---
libcxx/src/atomic.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp
index 18fa90b857cab..cea3ee4a8c2b4 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -159,7 +159,7 @@ static void __platform_wait_on_address(void const* __ptr, void const* __val, May
_umtx_op(const_cast<void*>(__ptr),
UMTX_OP_WAIT,
value,
- static_cast<void*>(static_cast<uintptr_t>(sizeof(timeout))),
+ reinterpret_cast<void*>(static_cast<uintptr_t>(sizeof(timeout))),
&timeout);
}
}
>From b1da70f5111ba604bf4cb2136e2b5dde1e98913a Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Fri, 13 Feb 2026 19:24:19 +0000
Subject: [PATCH 5/5] rebase
---
libcxx/src/atomic.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp
index cea3ee4a8c2b4..3948f8b037976 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -153,8 +153,8 @@ static void __platform_wait_on_address(void const* __ptr, void const* __val, May
_umtx_op(const_cast<void*>(__ptr), UMTX_OP_WAIT, value, nullptr, nullptr);
} else {
timespec timeout{};
- timeout.tv_sec = __timeout_ns / 1'000'000'000;
- timeout.tv_nsec = __timeout_ns % 1'000'000'000;
+ timeout.tv_sec = maybe_timeout_ns / 1'000'000'000;
+ timeout.tv_nsec = maybe_timeout_ns % 1'000'000'000;
_umtx_op(const_cast<void*>(__ptr),
UMTX_OP_WAIT,
More information about the libcxx-commits
mailing list