[libcxx-commits] [libcxx] fbdfff4 - [libc++] Use Fuchsia futex operations (#133571)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Apr 8 14:37:59 PDT 2026
Author: Roland McGrath
Date: 2026-04-08T17:37:54-04:00
New Revision: fbdfff47c7e4cdb29512bc78cad5978fa2a86ce9
URL: https://github.com/llvm/llvm-project/commit/fbdfff47c7e4cdb29512bc78cad5978fa2a86ce9
DIFF: https://github.com/llvm/llvm-project/commit/fbdfff47c7e4cdb29512bc78cad5978fa2a86ce9.diff
LOG: [libc++] Use Fuchsia futex operations (#133571)
The basic futex operations have always been available on Fuchsia.
Wire them up to properly support C++20 atomic notify_*/wait.
Added:
Modified:
libcxx/include/__atomic/contention_t.h
libcxx/include/__cxx03/__atomic/contention_t.h
libcxx/src/atomic.cpp
Removed:
################################################################################
diff --git a/libcxx/include/__atomic/contention_t.h b/libcxx/include/__atomic/contention_t.h
index b7e370439e67a..c6d2570696079 100644
--- a/libcxx/include/__atomic/contention_t.h
+++ b/libcxx/include/__atomic/contention_t.h
@@ -25,7 +25,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// instead.
#if defined(_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE)
-# ifdef __linux__
+# if defined(__linux__) || defined(__Fuchsia__)
using __cxx_contention_t _LIBCPP_NODEBUG = int32_t;
# elif defined(__APPLE__)
using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
@@ -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 a97f0668da2fe..c7ecf9d216d55 100644
--- a/libcxx/include/__cxx03/__atomic/contention_t.h
+++ b/libcxx/include/__cxx03/__atomic/contention_t.h
@@ -19,11 +19,11 @@
_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;
-#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 3948f8b037976..12ff253048e3e 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -51,6 +51,10 @@
# include <memory>
# include <windows.h>
+#elif defined(__Fuchsia__)
+
+# include <zircon/syscalls.h>
+
#else // <- Add other operating systems here
// Baseline needs no new headers
@@ -254,6 +258,37 @@ static void __platform_wake_by_address(void const* __ptr, bool __notify_one) {
}
}
+#elif defined(__Fuchsia__)
+
+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 reinterpret_cast<zx_futex_t const*>(__ptr);
+}
+
+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);
+}
+
+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
// Baseline is just a timed backoff
More information about the libcxx-commits
mailing list