[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 00:40:17 PST 2026


https://github.com/huixie90 updated https://github.com/llvm/llvm-project/pull/180400

>From b16a17b2d91ebf28ebeba7692c40e003d982de5b 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/4] [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 1277b20caf641..dd5a48f337d2f 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -138,17 +138,10 @@ static void __platform_wait_on_address(void const* __ptr, void const* __val, uin
   if (__timeout_ns == 0) {
     _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  = __timeout_ns / 1'000'000'000;
-    ut._timeout.tv_nsec = __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 57ca5e4d7b2f55fe8bba1fec36625648f8fa188b 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/4] 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 dd5a48f337d2f..a2ec66180fd29 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -138,10 +138,15 @@ static void __platform_wait_on_address(void const* __ptr, void const* __val, uin
   if (__timeout_ns == 0) {
     _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 b1ddd626c49061401b679dde30a8cdfff27a6ef3 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/4] 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 a2ec66180fd29..81472393d1178 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -133,10 +133,13 @@ static void __platform_wake_by_address(void const* __ptr, bool __notify_one) {
 template <std::size_t _Size>
 static void __platform_wait_on_address(void const* __ptr, void const* __val, uint64_t __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 (__timeout_ns == 0) {
-    _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;
@@ -144,7 +147,7 @@ static void __platform_wait_on_address(void const* __ptr, void const* __val, uin
 
     _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 edbaff1ccd5172eb4e30b73771662d9cf633f92b 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/4] 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 81472393d1178..2b995bfcb545e 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -148,7 +148,7 @@ static void __platform_wait_on_address(void const* __ptr, void const* __val, uin
     _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);
   }
 }



More information about the libcxx-commits mailing list