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 + #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(reinterpret_cast(&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