[libcxx-commits] [libcxx] [libc++] Use Fuchsia futex operations (PR #133571)

Roland McGrath via libcxx-commits libcxx-commits at lists.llvm.org
Thu Mar 26 18:54:33 PDT 2026


https://github.com/frobtech updated https://github.com/llvm/llvm-project/pull/133571

>From 8026b86be484df0cc59f11573fd37c1cb53580b0 Mon Sep 17 00:00:00 2001
From: Roland McGrath <mcgrathr at google.com>
Date: Sat, 29 Mar 2025 00:43:27 -0700
Subject: [PATCH 1/2] [libc++] Use Fuchsia futex operations

---
 libcxx/include/__atomic/contention_t.h        |  2 +-
 .../include/__cxx03/__atomic/contention_t.h   |  2 +-
 libcxx/src/atomic.cpp                         | 22 +++++++++++++++++++
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__atomic/contention_t.h b/libcxx/include/__atomic/contention_t.h
index 5b42a0125f875..cd3a8e4b29094 100644
--- a/libcxx/include/__atomic/contention_t.h
+++ b/libcxx/include/__atomic/contention_t.h
@@ -19,7 +19,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
+#if defined(__linux__) || defined(__Fuchsia__) || (defined(_AIX) && !defined(__64BIT__))
 using __cxx_contention_t _LIBCPP_NODEBUG = int32_t;
 #else
 using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
diff --git a/libcxx/include/__cxx03/__atomic/contention_t.h b/libcxx/include/__cxx03/__atomic/contention_t.h
index a97f0668da2fe..3fc3ccef78df5 100644
--- a/libcxx/include/__cxx03/__atomic/contention_t.h
+++ b/libcxx/include/__cxx03/__atomic/contention_t.h
@@ -19,7 +19,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
+#if defined(__linux__) || defined(__Fuchsia__) || (defined(_AIX) && !defined(__64BIT__))
 using __cxx_contention_t = int32_t;
 #else
 using __cxx_contention_t = int64_t;
diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp
index c1af8d6f95aae..6de355b534b08 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -41,6 +41,10 @@
 // OpenBSD has no indirect syscalls
 #  define _LIBCPP_FUTEX(...) futex(__VA_ARGS__)
 
+#elif defined(__Fuchsia__)
+
+#  include <zircon/syscalls.h>
+
 #else // <- Add other operating systems here
 
 // Baseline needs no new headers
@@ -101,6 +105,24 @@ static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const vo
   _umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr), UMTX_OP_WAKE, __notify_one ? 1 : INT_MAX, nullptr, nullptr);
 }
 
+#elif defined(__Fuchsia__)
+
+static inline zx_futex_t const* __libcpp_zx_futex(__cxx_atomic_contention_t const volatile* ptr) {
+  // Implicitly link against the vDSO system call ABI without requiring the
+  // final link to specify -lzircon explicitly when statically linking libc++.
+#  pragma comment(lib, "zircon")
+  return const_cast<zx_futex_t const*>(reinterpret_cast<zx_futex_t const volatile*>(&ptr->__a_value));
+}
+
+static void
+__libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr, __cxx_contention_t __val) {
+  _zx_futex_wait(__libcpp_zx_futex(__ptr), __val, ZX_HANDLE_INVALID, ZX_TIME_INFINITE);
+}
+
+static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr, bool __notify_one) {
+  _zx_futex_wake(__libcpp_zx_futex(__ptr), __notify_one ? 1 : UINT32_MAX);
+}
+
 #else // <- Add other operating systems here
 
 // Baseline is just a timed backoff

>From 3f749070028ed66a67fb908a032b6f8b234807ab Mon Sep 17 00:00:00 2001
From: Roland McGrath <mcgrathr at google.com>
Date: Thu, 26 Mar 2026 18:52:41 -0700
Subject: [PATCH 2/2] Update for current libc++ internals

---
 libcxx/include/__atomic/contention_t.h        |  6 ++---
 .../include/__cxx03/__atomic/contention_t.h   |  2 +-
 libcxx/src/atomic.cpp                         | 27 ++++++++++++++-----
 3 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/libcxx/include/__atomic/contention_t.h b/libcxx/include/__atomic/contention_t.h
index 8ce0e8edb531c..c6d2570696079 100644
--- a/libcxx/include/__atomic/contention_t.h
+++ b/libcxx/include/__atomic/contention_t.h
@@ -37,15 +37,15 @@ using __cxx_contention_t _LIBCPP_NODEBUG = int32_t;
 using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
 #  else
 using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
-#  endif // __linux__
+#  endif // __linux__ || __Fuchsia__
 
 #else // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
 
-#  if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
+#  if defined(__linux__) || defined(__Fuchsia__) || (defined(_AIX) && !defined(__64BIT__))
 using __cxx_contention_t _LIBCPP_NODEBUG = int32_t;
 #  else
 using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
-#  endif // __linux__ || (_AIX && !__64BIT__)
+#  endif // __linux__ || __Fuchsia__ || (_AIX && !__64BIT__)
 
 #endif // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
 
diff --git a/libcxx/include/__cxx03/__atomic/contention_t.h b/libcxx/include/__cxx03/__atomic/contention_t.h
index 3fc3ccef78df5..c7ecf9d216d55 100644
--- a/libcxx/include/__cxx03/__atomic/contention_t.h
+++ b/libcxx/include/__cxx03/__atomic/contention_t.h
@@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 using __cxx_contention_t = int32_t;
 #else
 using __cxx_contention_t = int64_t;
-#endif // __linux__ || (_AIX && !__64BIT__)
+#endif // __linux__ || __Fuchsia__ || (_AIX && !__64BIT__)
 
 using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
 
diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp
index edf39131b13d5..70bbe2e180902 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -260,20 +260,33 @@ static void __platform_wake_by_address(void const* __ptr, bool __notify_one) {
 
 #elif defined(__Fuchsia__)
 
-static inline zx_futex_t const* __libcpp_zx_futex(__cxx_atomic_contention_t const volatile* ptr) {
+template <std::size_t _Size>
+static inline zx_futex_t const* __get_zx_futex(void const* __ptr) {
+  static_assert(_Size == sizeof(zx_futex_t), "Can only wait/wake on zx_futex_t-compatible value");
+
   // Implicitly link against the vDSO system call ABI without requiring the
   // final link to specify -lzircon explicitly when statically linking libc++.
 #  pragma comment(lib, "zircon")
-  return const_cast<zx_futex_t const*>(reinterpret_cast<zx_futex_t const volatile*>(&ptr->__a_value));
+
+  return const_cast<zx_futex_t const*>(reinterpret_cast<zx_futex_t const*>(__ptr));
 }
 
-static void
-__libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr, __cxx_contention_t __val) {
-  _zx_futex_wait(__libcpp_zx_futex(__ptr), __val, ZX_HANDLE_INVALID, ZX_TIME_INFINITE);
+template <std::size_t _Size, class MaybeTimeout>
+static void __platform_wait_on_address(void const* __ptr, void const* __val, MaybeTimeout maybe_timeout_ns) {
+  zx_futex_t val;
+  std::memcpy(&val, __val, _Size);
+  zx_instant_mono_t deadline;
+  if constexpr (is_same_v<MaybeTimeout, NoTimeout>) {
+    deadline = ZX_TIME_INFINITE;
+  } else {
+    deadline = _zx_deadline_after(maybe_timeout_ns);
+  }
+  _zx_futex_wait(__get_zx_futex<_Size>(__ptr), val, ZX_HANDLE_INVALID, deadline);
 }
 
-static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr, bool __notify_one) {
-  _zx_futex_wake(__libcpp_zx_futex(__ptr), __notify_one ? 1 : UINT32_MAX);
+template <std::size_t _Size>
+static void __platform_wake_by_address(void const* __ptr, bool __notify_one) {
+  _zx_futex_wake(__get_zx_futex<_Size>(__ptr), __notify_one ? 1 : UINT32_MAX);
 }
 
 #else // <- Add other operating systems here



More information about the libcxx-commits mailing list