[libcxx-commits] [libcxx] [libc++] atomic timed wait (PR #172214)

via libcxx-commits libcxx-commits at lists.llvm.org
Sun Jan 18 04:44:36 PST 2026


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

>From 4bd17979bb0ca588a87c8e899550f5b1e4d2fecc Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sun, 14 Dec 2025 15:11:31 +0000
Subject: [PATCH 01/13] [libc++] atomic timed wait

---
 libcxx/include/CMakeLists.txt                 |   1 +
 libcxx/include/__atomic/atomic_sync_timed.h   | 143 ++++++++++++++++++
 .../include/__atomic/atomic_waitable_traits.h |   1 -
 libcxx/include/__thread/poll_with_backoff.h   |   1 +
 .../include/__thread/timed_backoff_policy.h   |   1 +
 libcxx/include/atomic                         |   1 +
 libcxx/include/module.modulemap.in            |   1 +
 libcxx/include/semaphore                      |   8 +-
 libcxx/src/atomic.cpp                         |  87 ++++++++---
 9 files changed, 219 insertions(+), 25 deletions(-)
 create mode 100644 libcxx/include/__atomic/atomic_sync_timed.h

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 2ccc766f8109b..51f75106f4f5d 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -214,6 +214,7 @@ set(files
   __atomic/atomic_lock_free.h
   __atomic/atomic_ref.h
   __atomic/atomic_sync.h
+  __atomic/atomic_sync_timed.h
   __atomic/atomic_waitable_traits.h
   __atomic/check_memory_order.h
   __atomic/contention_t.h
diff --git a/libcxx/include/__atomic/atomic_sync_timed.h b/libcxx/include/__atomic/atomic_sync_timed.h
new file mode 100644
index 0000000000000..ca7502b64c304
--- /dev/null
+++ b/libcxx/include/__atomic/atomic_sync_timed.h
@@ -0,0 +1,143 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ATOMIC_ATOMIC_SYNC_TIMED_H
+#define _LIBCPP___ATOMIC_ATOMIC_SYNC_TIMED_H
+
+#include <__atomic/atomic_waitable_traits.h>
+#include <__atomic/contention_t.h>
+#include <__atomic/memory_order.h>
+#include <__atomic/to_gcc_order.h>
+#include <__chrono/duration.h>
+#include <__config>
+#include <__memory/addressof.h>
+#include <__thread/poll_with_backoff.h>
+#include <__type_traits/conjunction.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/has_unique_object_representation.h>
+#include <__type_traits/invoke.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_trivially_copyable.h>
+#include <__type_traits/void_t.h>
+#include <__utility/declval.h>
+#include <cstdint>
+#include <cstring>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+#  if _LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
+
+_LIBCPP_AVAILABILITY_NEW_SYNC
+    _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __atomic_monitor_global(void const* __address) _NOEXCEPT;
+
+// wait on the global contention state to be changed from the given value for the address
+_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_global_table_with_timeout(
+    void const* __address, __cxx_contention_t __monitor_value, uint64_t __timeout_ns) _NOEXCEPT;
+
+// wait on the address directly with the native platform wait
+template <std::size_t _Size>
+_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void
+__atomic_wait_native_with_timeout(void const* __address, void const* __old_value, uint64_t __timeout_ns) _NOEXCEPT;
+
+template <class _AtomicWaitable, class _Poll, class _Rep, class _Period>
+struct __atomic_wait_timed_backoff_impl {
+  const _AtomicWaitable& __a_;
+  _Poll __poll_;
+  memory_order __order_;
+  chrono::duration<_Rep, _Period> __rel_time_;
+
+  using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >;
+  using __value_type _LIBCPP_NODEBUG      = typename __waitable_traits::__value_type;
+
+  _LIBCPP_HIDE_FROM_ABI __backoff_results operator()(chrono::nanoseconds __elapsed) const {
+    if (__elapsed > chrono::microseconds(4)) {
+      auto __contention_address = const_cast<const void*>(
+          static_cast<const volatile void*>(__waitable_traits::__atomic_contention_address(__a_)));
+
+      uint64_t __timeout_ns =
+          static_cast<uint64_t>((chrono::duration_cast<chrono::nanoseconds>(__rel_time_) - __elapsed).count());
+
+      if constexpr (__has_native_atomic_wait<__value_type>) {
+        auto __atomic_value = __waitable_traits::__atomic_load(__a_, __order_);
+        if (__poll_(__atomic_value))
+          return __backoff_results::__poll_success;
+        std::__atomic_wait_native_with_timeout<sizeof(__value_type)>(
+            __contention_address, std::addressof(__atomic_value), __timeout_ns);
+      } else {
+        __cxx_contention_t __monitor_val = std::__atomic_monitor_global(__contention_address);
+        auto __atomic_value              = __waitable_traits::__atomic_load(__a_, __order_);
+        if (__poll_(__atomic_value))
+          return __backoff_results::__poll_success;
+        std::__atomic_wait_global_table_with_timeout(__contention_address, __monitor_val, __timeout_ns);
+      }
+    } else {
+    } // poll
+    return __backoff_results::__continue_poll;
+  }
+};
+
+// The semantics of this function are similar to `atomic`'s
+// `.wait(T old, std::memory_order order)`, but instead of having a hardcoded
+// predicate (is the loaded value unequal to `old`?), the predicate function is
+// specified as an argument. The loaded value is given as an in-out argument to
+// the predicate. If the predicate function returns `true`,
+// `__atomic_wait_unless` will return. If the predicate function returns
+// `false`, it must set the argument to its current understanding of the atomic
+// value. The predicate function must not return `false` spuriously.
+template <class _AtomicWaitable, class _Poll, class _Rep, class _Period>
+_LIBCPP_HIDE_FROM_ABI bool __atomic_wait_unless_with_timeout(
+    const _AtomicWaitable& __a,
+    memory_order __order,
+    _Poll&& __poll,
+    chrono::duration<_Rep, _Period> const& __rel_time) {
+  static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
+  __atomic_wait_timed_backoff_impl<_AtomicWaitable, __decay_t<_Poll>, _Rep, _Period> __backoff_fn = {
+      __a, __poll, __order, __rel_time};
+  auto __poll_result = std::__libcpp_thread_poll_with_backoff(
+      /* poll */
+      [&]() {
+        auto __current_val = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_load(__a, __order);
+        return __poll(__current_val);
+      },
+      /* backoff */ __backoff_fn,
+      __rel_time);
+
+  return __poll_result == __poll_with_backoff_results::__poll_success;
+}
+
+#  else // _LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
+
+template <class _AtomicWaitable, class _Poll, class _Rep, class _Period>
+_LIBCPP_HIDE_FROM_ABI bool __atomic_wait_unless_with_timeout(
+    const _AtomicWaitable& __a,
+    memory_order __order,
+    _Poll&& __poll,
+    chrono::duration<_Rep, _Period> const& __rel_time) {
+  auto __res = std::__libcpp_thread_poll_with_backoff(
+      /* poll */
+      [&]() {
+        auto __current_val = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_load(__a, __order);
+        return __poll(__current_val);
+      },
+      /* backoff */ __libcpp_timed_backoff_policy(),
+      __rel_time);
+  return __res == __poll_with_backoff_results::__poll_success;
+}
+
+#  endif // _LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
+
+#endif // C++20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ATOMIC_ATOMIC_SYNC_TIMED_H
diff --git a/libcxx/include/__atomic/atomic_waitable_traits.h b/libcxx/include/__atomic/atomic_waitable_traits.h
index de06fe70b3e1a..fda2780842911 100644
--- a/libcxx/include/__atomic/atomic_waitable_traits.h
+++ b/libcxx/include/__atomic/atomic_waitable_traits.h
@@ -5,7 +5,6 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-
 #ifndef _LIBCPP___ATOMIC_ATOMIC_WAITABLE_TRAITS_H
 #define _LIBCPP___ATOMIC_ATOMIC_WAITABLE_TRAITS_H
 
diff --git a/libcxx/include/__thread/poll_with_backoff.h b/libcxx/include/__thread/poll_with_backoff.h
index e007e7746ca52..97b7374779924 100644
--- a/libcxx/include/__thread/poll_with_backoff.h
+++ b/libcxx/include/__thread/poll_with_backoff.h
@@ -13,6 +13,7 @@
 #include <__chrono/duration.h>
 #include <__chrono/high_resolution_clock.h>
 #include <__config>
+#include <cstdint>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
diff --git a/libcxx/include/__thread/timed_backoff_policy.h b/libcxx/include/__thread/timed_backoff_policy.h
index 01fe2dd045e58..3ef90bede719d 100644
--- a/libcxx/include/__thread/timed_backoff_policy.h
+++ b/libcxx/include/__thread/timed_backoff_policy.h
@@ -10,6 +10,7 @@
 #ifndef _LIBCPP___THREAD_TIMED_BACKOFF_POLICY_H
 #define _LIBCPP___THREAD_TIMED_BACKOFF_POLICY_H
 
+#include "__thread/poll_with_backoff.h"
 #include <__config>
 #include <__thread/poll_with_backoff.h>
 
diff --git a/libcxx/include/atomic b/libcxx/include/atomic
index 3323650f7f81a..23a3db5d35029 100644
--- a/libcxx/include/atomic
+++ b/libcxx/include/atomic
@@ -608,6 +608,7 @@ template <class T>
 #  include <__atomic/atomic_init.h>
 #  include <__atomic/atomic_lock_free.h>
 #  include <__atomic/atomic_sync.h>
+#  include <__atomic/atomic_sync_timed.h>
 #  include <__atomic/atomic_waitable_traits.h>
 #  include <__atomic/check_memory_order.h>
 #  include <__atomic/contention_t.h>
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index cbe1e221844f8..68c14db3b89e9 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -869,6 +869,7 @@ module std [system] {
     module atomic_lock_free       { header "__atomic/atomic_lock_free.h" }
     module atomic_ref             { header "__atomic/atomic_ref.h" }
     module atomic_sync            { header "__atomic/atomic_sync.h" }
+    module atomic_sync_timed      { header "__atomic/atomic_sync_timed.h" }
     module atomic_waitable_traits { header "__atomic/atomic_waitable_traits.h" }
     module atomic {
       header "__atomic/atomic.h"
diff --git a/libcxx/include/semaphore b/libcxx/include/semaphore
index 7c1637356bfe5..f93f8243bb15a 100644
--- a/libcxx/include/semaphore
+++ b/libcxx/include/semaphore
@@ -55,6 +55,7 @@ using binary_semaphore = counting_semaphore<1>; // since C++20
 #    include <__assert>
 #    include <__atomic/atomic.h>
 #    include <__atomic/atomic_sync.h>
+#    include <__atomic/atomic_sync_timed.h>
 #    include <__atomic/memory_order.h>
 #    include <__chrono/time_point.h>
 #    include <__cstddef/ptrdiff_t.h>
@@ -107,9 +108,10 @@ public:
   _LIBCPP_HIDE_FROM_ABI bool try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time) {
     if (__rel_time == chrono::duration<_Rep, _Period>::zero())
       return try_acquire();
-    auto const __poll_fn = [this]() { return try_acquire(); };
-    return std::__libcpp_thread_poll_with_backoff(__poll_fn, __libcpp_timed_backoff_policy(), __rel_time) ==
-           __poll_with_backoff_results::__poll_success;
+
+    return std::__atomic_wait_unless_with_timeout(__a_, memory_order_relaxed, [this](ptrdiff_t& __old) {
+      return __try_acquire_impl(__old);
+    }, __rel_time);
   }
   _LIBCPP_HIDE_FROM_ABI bool try_acquire() {
     auto __old = __a_.load(memory_order_relaxed);
diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp
index 33ca5410923b6..19101a95d0c97 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -10,6 +10,7 @@
 #include <atomic>
 #include <climits>
 #include <cstddef>
+#include <cstdint>
 #include <cstring>
 #include <functional>
 #include <new>
@@ -63,11 +64,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #ifdef __linux__
 
 template <std::size_t _Size>
-static void __platform_wait_on_address(void const* __ptr, void const* __val) {
+static void __platform_wait_on_address(void const* __ptr, void const* __val, uint64_t __timeout_ns) {
   static_assert(_Size == 4, "Can only wait on 4 bytes value");
   char buffer[_Size];
   std::memcpy(&buffer, const_cast<const void*>(__val), _Size);
-  static constexpr timespec __timeout = {2, 0};
+  static constexpr timespec __default_timeout = {2, 0};
+  timespec __timeout;
+  if (__timeout_ns == 0) {
+    __timeout = __default_timeout;
+  } else {
+    __timeout.tv_sec  = __timeout_ns / 1'000'000'000;
+    __timeout.tv_nsec = __timeout_ns % 1'000'000'000;
+  }
   _LIBCPP_FUTEX(__ptr, FUTEX_WAIT_PRIVATE, *reinterpret_cast<__cxx_contention_t const*>(&buffer), &__timeout, 0, 0);
 }
 
@@ -89,14 +97,17 @@ extern "C" int __ulock_wake(uint32_t operation, void* addr, uint64_t wake_value)
 #  define ULF_WAKE_ALL 0x00000100
 
 template <std::size_t _Size>
-static void __platform_wait_on_address(void const* __ptr, void const* __val) {
+static void __platform_wait_on_address(void const* __ptr, void const* __val, uint64_t __timeout_ns) {
   static_assert(_Size == 8 || _Size == 4, "Can only wait on 8 bytes or 4 bytes value");
   char buffer[_Size];
   std::memcpy(&buffer, const_cast<const void*>(__val), _Size);
+  auto __timeout_us = __timeout_ns == 0 ? 0 : static_cast<uint32_t>(__timeout_ns / 1000);
   if constexpr (_Size == 4)
-    __ulock_wait(UL_COMPARE_AND_WAIT, const_cast<void*>(__ptr), *reinterpret_cast<uint32_t const*>(&buffer), 0);
+    __ulock_wait(
+        UL_COMPARE_AND_WAIT, const_cast<void*>(__ptr), *reinterpret_cast<uint32_t const*>(&buffer), __timeout_us);
   else
-    __ulock_wait(UL_COMPARE_AND_WAIT64, const_cast<void*>(__ptr), *reinterpret_cast<uint64_t const*>(&buffer), 0);
+    __ulock_wait(
+        UL_COMPARE_AND_WAIT64, const_cast<void*>(__ptr), *reinterpret_cast<uint64_t const*>(&buffer), __timeout_us);
 }
 
 template <std::size_t _Size>
@@ -117,11 +128,20 @@ 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) {
+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");
-  char buffer[_Size];
-  std::memcpy(&buffer, const_cast<const void*>(__val), _Size);
-  _umtx_op(const_cast<void*>(__ptr), UMTX_OP_WAIT, *reinterpret_cast<__cxx_contention_t*>(&buffer), nullptr, nullptr);
+  if (__timeout_ns == 0) {
+    char buffer[_Size];
+    std::memcpy(&buffer, const_cast<const void*>(__val), _Size);
+    _umtx_op(const_cast<void*>(__ptr), UMTX_OP_WAIT, *reinterpret_cast<__cxx_contention_t*>(&buffer), nullptr, nullptr);
+  } else {
+    // TODO the doc says it supports timeout but does not say how to use it
+    // https://man.freebsd.org/cgi/man.cgi?query=_umtx_op
+    __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));
+  }
 }
 
 template <std::size_t _Size>
@@ -157,17 +177,21 @@ static void* win32_get_synch_api_function(const char* function_name) {
 }
 
 template <std::size_t _Size>
-static void __platform_wait_on_address(void const* __ptr, void const* __val) {
+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");
   // WaitOnAddress was added in Windows 8 (build 9200)
   static auto wait_on_address =
       reinterpret_cast<BOOL(WINAPI*)(void*, PVOID, SIZE_T, DWORD)>(win32_get_synch_api_function("WaitOnAddress"));
   if (wait_on_address != nullptr) {
-    wait_on_address(const_cast<void*>(__ptr), const_cast<void*>(__val), _Size, INFINITE);
+    wait_on_address(const_cast<void*>(__ptr),
+                    const_cast<void*>(__val),
+                    _Size,
+                    __timeout_ns == 0 ? INFINITE : static_cast<DWORD>(__timeout_ns / 1'000'000));
   } else {
     __libcpp_thread_poll_with_backoff(
         [=]() -> bool { return std::memcmp(const_cast<const void*>(__ptr), __val, _Size) != 0; },
-        __libcpp_timed_backoff_policy());
+        __libcpp_timed_backoff_policy(),
+        std::chrono::nanoseconds(__timeout_ns));
   }
 }
 
@@ -202,10 +226,11 @@ static void __platform_wake_by_address(void const* __ptr, bool __notify_one) {
 // Baseline is just a timed backoff
 
 template <std::size_t _Size>
-static void __platform_wait_on_address(void const* __ptr, void const* __val) {
+static void __platform_wait_on_address(void const* __ptr, void const* __val, uint64_t __timeout_ns) {
   __libcpp_thread_poll_with_backoff(
       [=]() -> bool { return std::memcmp(const_cast<const void*>(__ptr), __val, _Size) != 0; },
-      __libcpp_timed_backoff_policy());
+      __libcpp_timed_backoff_policy(),
+      std::chrono::nanoseconds(__timeout_ns));
 }
 
 template <std::size_t _Size>
@@ -229,14 +254,16 @@ __contention_notify(__cxx_atomic_contention_t* __waiter_count, void const* __add
 }
 
 template <std::size_t _Size>
-static void
-__contention_wait(__cxx_atomic_contention_t* __waiter_count, void const* __address_to_wait, void const* __old_value) {
+static void __contention_wait(__cxx_atomic_contention_t* __waiter_count,
+                              void const* __address_to_wait,
+                              void const* __old_value,
+                              uint64_t __timeout_ns) {
   __cxx_atomic_fetch_add(__waiter_count, __cxx_contention_t(1), memory_order_relaxed);
   // https://llvm.org/PR109290
   // There are no platform guarantees of a memory barrier in the platform wait implementation
   __cxx_atomic_thread_fence(memory_order_seq_cst);
   // We sleep as long as the monitored value hasn't changed.
-  __platform_wait_on_address<_Size>(__address_to_wait, __old_value);
+  __platform_wait_on_address<_Size>(__address_to_wait, __old_value, __timeout_ns);
   __cxx_atomic_fetch_sub(__waiter_count, __cxx_contention_t(1), memory_order_release);
 }
 
@@ -299,7 +326,14 @@ _LIBCPP_EXPORTED_FROM_ABI void
 __atomic_wait_global_table(void const* __location, __cxx_contention_t __old_value) noexcept {
   auto const __entry = __get_global_contention_state(__location);
   __contention_wait<sizeof(__cxx_atomic_contention_t)>(
-      &__entry->__waiter_count, &__entry->__platform_state, &__old_value);
+      &__entry->__waiter_count, &__entry->__platform_state, &__old_value, 0);
+}
+
+_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_global_table_with_timeout(
+    void const* __location, __cxx_contention_t __old_value, uint64_t __timeout_ns) _NOEXCEPT {
+  auto const __entry = __get_global_contention_state(__location);
+  __contention_wait<sizeof(__cxx_atomic_contention_t)>(
+      &__entry->__waiter_count, &__entry->__platform_state, &__old_value, __timeout_ns);
 }
 
 _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_global_table(void const* __location) noexcept {
@@ -314,7 +348,13 @@ _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_global_table(void const* __lo
 
 template <std::size_t _Size>
 _LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_native(void const* __address, void const* __old_value) noexcept {
-  __contention_wait<_Size>(__get_native_waiter_count(__address), __address, __old_value);
+  __contention_wait<_Size>(__get_native_waiter_count(__address), __address, __old_value, 0);
+}
+
+template <std::size_t _Size>
+_LIBCPP_EXPORTED_FROM_ABI void
+__atomic_wait_native_with_timeout(void const* __address, void const* __old_value, uint64_t __timeout_ns) noexcept {
+  __contention_wait<_Size>(__get_native_waiter_count(__address), __address, __old_value, __timeout_ns);
 }
 
 template <std::size_t _Size>
@@ -335,6 +375,8 @@ _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_native(void const* __location
 
 #  define _INSTANTIATE(_SIZE)                                                                                          \
     template _LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_native<_SIZE>(void const*, void const*) noexcept;            \
+    template _LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_native_with_timeout<_SIZE>(                                  \
+        void const*, void const*, uint64_t) noexcept;                                                                  \
     template _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_native<_SIZE>(void const*) noexcept;                   \
     template _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_native<_SIZE>(void const*) noexcept;
 
@@ -347,6 +389,9 @@ _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_INSTANTIATE)
 template _LIBCPP_EXPORTED_FROM_ABI void
 __atomic_wait_native<sizeof(__cxx_contention_t)>(void const* __address, void const* __old_value) noexcept;
 
+template _LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_native_with_timeout<sizeof(__cxx_contention_t)>(
+    void const* __address, void const* __old_value, uint64_t) noexcept;
+
 template _LIBCPP_EXPORTED_FROM_ABI void
 __atomic_notify_one_native<sizeof(__cxx_contention_t)>(void const* __location) noexcept;
 
@@ -378,7 +423,7 @@ _LIBCPP_EXPORTED_FROM_ABI void
 __libcpp_atomic_wait(void const volatile* __location, __cxx_contention_t __old_value) noexcept {
   auto const __entry = __get_global_contention_state(const_cast<void const*>(__location));
   __contention_wait<sizeof(__cxx_atomic_contention_t)>(
-      &__entry->__waiter_count, &__entry->__platform_state, &__old_value);
+      &__entry->__waiter_count, &__entry->__platform_state, &__old_value, 0);
 }
 
 _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile* __location) noexcept {
@@ -397,7 +442,7 @@ _LIBCPP_EXPORTED_FROM_ABI void
 __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile* __location, __cxx_contention_t __old_value) noexcept {
   auto __location_cast = const_cast<const void*>(static_cast<const volatile void*>(__location));
   __contention_wait<sizeof(__cxx_atomic_contention_t)>(
-      __get_native_waiter_count(__location_cast), __location_cast, &__old_value);
+      __get_native_waiter_count(__location_cast), __location_cast, &__old_value, 0);
 }
 
 // this function is even unused in the old ABI

>From fd29b877da4e53881db49b7b72ee67d9d1d14688 Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sat, 20 Dec 2025 13:35:12 +0000
Subject: [PATCH 02/13] test

---
 libcxx/test/benchmarks/semaphore.bench.cpp    | 23 ++++++++
 .../lost_wakeup.timed.pass.cpp                | 53 +++++++++++++++++++
 2 files changed, 76 insertions(+)
 create mode 100644 libcxx/test/benchmarks/semaphore.bench.cpp
 create mode 100644 libcxx/test/std/thread/thread.semaphore/lost_wakeup.timed.pass.cpp

diff --git a/libcxx/test/benchmarks/semaphore.bench.cpp b/libcxx/test/benchmarks/semaphore.bench.cpp
new file mode 100644
index 0000000000000..f8c03d8299413
--- /dev/null
+++ b/libcxx/test/benchmarks/semaphore.bench.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// ADDITIONAL_COMPILE_FLAGS: -O3
+
+#include <cstdint>
+#include <optional>
+#include <semaphore>
+#include <thread>
+
+#include "benchmark/benchmark.h"
+#include "make_test_thread.h"
+
+
+
+void BM_semaphore_timed_acquire(benchmark::State& state) {
+}
\ No newline at end of file
diff --git a/libcxx/test/std/thread/thread.semaphore/lost_wakeup.timed.pass.cpp b/libcxx/test/std/thread/thread.semaphore/lost_wakeup.timed.pass.cpp
new file mode 100644
index 0000000000000..85a8fbf1ff288
--- /dev/null
+++ b/libcxx/test/std/thread/thread.semaphore/lost_wakeup.timed.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-threads
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// ADDITIONAL_COMPILE_FLAGS: -O3
+
+// <semaphore>
+
+#include <barrier>
+#include <chrono>
+#include <semaphore>
+#include <thread>
+#include <vector>
+
+#include "make_test_thread.h"
+
+static std::counting_semaphore<> s(0);
+constexpr auto num_acquirer   = 100;
+constexpr auto num_iterations = 50000;
+static std::barrier<> b(num_acquirer + 1);
+
+void acquire() {
+  for (int i = 0; i < num_iterations; ++i) {
+    while (!s.try_acquire_for(std::chrono::seconds(1))) {
+    }
+  }
+}
+
+void release() {
+  for (int i = 0; i < num_iterations; ++i) {
+      s.release(num_acquirer);
+  }
+}
+
+int main(int, char**) {
+  std::vector<std::thread> threads;
+  for (int i = 0; i < num_acquirer; ++i)
+    threads.push_back(support::make_test_thread(acquire));
+
+  threads.push_back(support::make_test_thread(release));
+
+  for (auto& thread : threads)
+    thread.join();
+
+  return 0;
+}

>From ab99fa81617df101a06c3ee25e3ec19f63f329f8 Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Wed, 7 Jan 2026 21:15:05 +0000
Subject: [PATCH 03/13] rebase

---
 libcxx/include/__atomic/atomic_sync_timed.h      | 6 +++---
 libcxx/include/__atomic/atomic_waitable_traits.h | 1 +
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/libcxx/include/__atomic/atomic_sync_timed.h b/libcxx/include/__atomic/atomic_sync_timed.h
index ca7502b64c304..3b1db1f86320c 100644
--- a/libcxx/include/__atomic/atomic_sync_timed.h
+++ b/libcxx/include/__atomic/atomic_sync_timed.h
@@ -87,11 +87,11 @@ struct __atomic_wait_timed_backoff_impl {
 };
 
 // The semantics of this function are similar to `atomic`'s
-// `.wait(T old, std::memory_order order)`, but instead of having a hardcoded
+// `.wait(T old, std::memory_order order)` with a timeout, but instead of having a hardcoded
 // predicate (is the loaded value unequal to `old`?), the predicate function is
 // specified as an argument. The loaded value is given as an in-out argument to
 // the predicate. If the predicate function returns `true`,
-// `__atomic_wait_unless` will return. If the predicate function returns
+// `__atomic_wait_unless_with_timeout` will return. If the predicate function returns
 // `false`, it must set the argument to its current understanding of the atomic
 // value. The predicate function must not return `false` spuriously.
 template <class _AtomicWaitable, class _Poll, class _Rep, class _Period>
@@ -100,7 +100,7 @@ _LIBCPP_HIDE_FROM_ABI bool __atomic_wait_unless_with_timeout(
     memory_order __order,
     _Poll&& __poll,
     chrono::duration<_Rep, _Period> const& __rel_time) {
-  static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
+  static_assert(__atomic_waitable<_AtomicWaitable>, "");
   __atomic_wait_timed_backoff_impl<_AtomicWaitable, __decay_t<_Poll>, _Rep, _Period> __backoff_fn = {
       __a, __poll, __order, __rel_time};
   auto __poll_result = std::__libcpp_thread_poll_with_backoff(
diff --git a/libcxx/include/__atomic/atomic_waitable_traits.h b/libcxx/include/__atomic/atomic_waitable_traits.h
index fda2780842911..de06fe70b3e1a 100644
--- a/libcxx/include/__atomic/atomic_waitable_traits.h
+++ b/libcxx/include/__atomic/atomic_waitable_traits.h
@@ -5,6 +5,7 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
+
 #ifndef _LIBCPP___ATOMIC_ATOMIC_WAITABLE_TRAITS_H
 #define _LIBCPP___ATOMIC_ATOMIC_WAITABLE_TRAITS_H
 

>From 9f931241a3437dd175b76421898a250b6a121f8c Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Wed, 7 Jan 2026 21:27:33 +0000
Subject: [PATCH 04/13] update

---
 libcxx/include/__thread/poll_with_backoff.h   |  1 -
 .../include/__thread/timed_backoff_policy.h   |  1 -
 libcxx/include/semaphore                      |  2 --
 libcxx/test/benchmarks/semaphore.bench.cpp    | 23 -------------------
 4 files changed, 27 deletions(-)
 delete mode 100644 libcxx/test/benchmarks/semaphore.bench.cpp

diff --git a/libcxx/include/__thread/poll_with_backoff.h b/libcxx/include/__thread/poll_with_backoff.h
index 97b7374779924..e007e7746ca52 100644
--- a/libcxx/include/__thread/poll_with_backoff.h
+++ b/libcxx/include/__thread/poll_with_backoff.h
@@ -13,7 +13,6 @@
 #include <__chrono/duration.h>
 #include <__chrono/high_resolution_clock.h>
 #include <__config>
-#include <cstdint>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
diff --git a/libcxx/include/__thread/timed_backoff_policy.h b/libcxx/include/__thread/timed_backoff_policy.h
index 3ef90bede719d..01fe2dd045e58 100644
--- a/libcxx/include/__thread/timed_backoff_policy.h
+++ b/libcxx/include/__thread/timed_backoff_policy.h
@@ -10,7 +10,6 @@
 #ifndef _LIBCPP___THREAD_TIMED_BACKOFF_POLICY_H
 #define _LIBCPP___THREAD_TIMED_BACKOFF_POLICY_H
 
-#include "__thread/poll_with_backoff.h"
 #include <__config>
 #include <__thread/poll_with_backoff.h>
 
diff --git a/libcxx/include/semaphore b/libcxx/include/semaphore
index f93f8243bb15a..bfbe0b0239687 100644
--- a/libcxx/include/semaphore
+++ b/libcxx/include/semaphore
@@ -59,9 +59,7 @@ using binary_semaphore = counting_semaphore<1>; // since C++20
 #    include <__atomic/memory_order.h>
 #    include <__chrono/time_point.h>
 #    include <__cstddef/ptrdiff_t.h>
-#    include <__thread/poll_with_backoff.h>
 #    include <__thread/support.h>
-#    include <__thread/timed_backoff_policy.h>
 #    include <limits>
 #    include <version>
 
diff --git a/libcxx/test/benchmarks/semaphore.bench.cpp b/libcxx/test/benchmarks/semaphore.bench.cpp
deleted file mode 100644
index f8c03d8299413..0000000000000
--- a/libcxx/test/benchmarks/semaphore.bench.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-// ADDITIONAL_COMPILE_FLAGS: -O3
-
-#include <cstdint>
-#include <optional>
-#include <semaphore>
-#include <thread>
-
-#include "benchmark/benchmark.h"
-#include "make_test_thread.h"
-
-
-
-void BM_semaphore_timed_acquire(benchmark::State& state) {
-}
\ No newline at end of file

>From f22dd069620ec139e5f095ec2832cf78386c4b44 Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sat, 17 Jan 2026 13:58:09 +0000
Subject: [PATCH 05/13] review

---
 libcxx/include/__atomic/atomic_sync_timed.h              | 2 +-
 libcxx/include/semaphore                                 | 5 ++---
 libcxx/src/atomic.cpp                                    | 2 +-
 .../thread/thread.semaphore/lost_wakeup.timed.pass.cpp   | 9 +++++----
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/libcxx/include/__atomic/atomic_sync_timed.h b/libcxx/include/__atomic/atomic_sync_timed.h
index 3b1db1f86320c..297fd29971808 100644
--- a/libcxx/include/__atomic/atomic_sync_timed.h
+++ b/libcxx/include/__atomic/atomic_sync_timed.h
@@ -38,7 +38,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #  if _LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
 
 _LIBCPP_AVAILABILITY_NEW_SYNC
-    _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __atomic_monitor_global(void const* __address) _NOEXCEPT;
+_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __atomic_monitor_global(void const* __address) _NOEXCEPT;
 
 // wait on the global contention state to be changed from the given value for the address
 _LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_global_table_with_timeout(
diff --git a/libcxx/include/semaphore b/libcxx/include/semaphore
index bfbe0b0239687..d411d205cdf2d 100644
--- a/libcxx/include/semaphore
+++ b/libcxx/include/semaphore
@@ -107,9 +107,8 @@ public:
     if (__rel_time == chrono::duration<_Rep, _Period>::zero())
       return try_acquire();
 
-    return std::__atomic_wait_unless_with_timeout(__a_, memory_order_relaxed, [this](ptrdiff_t& __old) {
-      return __try_acquire_impl(__old);
-    }, __rel_time);
+    return std::__atomic_wait_unless_with_timeout(
+        __a_, memory_order_relaxed, [this](ptrdiff_t& __old) { return __try_acquire_impl(__old); }, __rel_time);
   }
   _LIBCPP_HIDE_FROM_ABI bool try_acquire() {
     auto __old = __a_.load(memory_order_relaxed);
diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp
index 19101a95d0c97..4ac9bdb4c01cb 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -329,7 +329,7 @@ __atomic_wait_global_table(void const* __location, __cxx_contention_t __old_valu
       &__entry->__waiter_count, &__entry->__platform_state, &__old_value, 0);
 }
 
-_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_global_table_with_timeout(
+_LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_global_table_with_timeout(
     void const* __location, __cxx_contention_t __old_value, uint64_t __timeout_ns) _NOEXCEPT {
   auto const __entry = __get_global_contention_state(__location);
   __contention_wait<sizeof(__cxx_atomic_contention_t)>(
diff --git a/libcxx/test/std/thread/thread.semaphore/lost_wakeup.timed.pass.cpp b/libcxx/test/std/thread/thread.semaphore/lost_wakeup.timed.pass.cpp
index 85a8fbf1ff288..aa18b8fc61a39 100644
--- a/libcxx/test/std/thread/thread.semaphore/lost_wakeup.timed.pass.cpp
+++ b/libcxx/test/std/thread/thread.semaphore/lost_wakeup.timed.pass.cpp
@@ -9,10 +9,11 @@
 // UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03, c++11, c++14, c++17
 
-// ADDITIONAL_COMPILE_FLAGS: -O3
-
 // <semaphore>
 
+// Test that counting_semaphore::try_acquire_for does not suffer from lost wakeup
+// under stress testing.
+
 #include <barrier>
 #include <chrono>
 #include <semaphore>
@@ -23,7 +24,7 @@
 
 static std::counting_semaphore<> s(0);
 constexpr auto num_acquirer   = 100;
-constexpr auto num_iterations = 50000;
+constexpr auto num_iterations = 5000;
 static std::barrier<> b(num_acquirer + 1);
 
 void acquire() {
@@ -35,7 +36,7 @@ void acquire() {
 
 void release() {
   for (int i = 0; i < num_iterations; ++i) {
-      s.release(num_acquirer);
+    s.release(num_acquirer);
   }
 }
 

>From c60017bbe376828c9c125323d4b5597991dddded Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sat, 17 Jan 2026 14:03:04 +0000
Subject: [PATCH 06/13] abi

---
 libcxx/include/__atomic/atomic_sync_timed.h                   | 1 +
 ...-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist | 3 +++
 ...nux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist | 4 ++++
 ...werpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist | 4 ++++
 ...rpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist | 4 ++++
 ...nux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist | 4 ++++
 ...known-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist | 4 ++++
 ...own-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist | 4 ++++
 8 files changed, 28 insertions(+)

diff --git a/libcxx/include/__atomic/atomic_sync_timed.h b/libcxx/include/__atomic/atomic_sync_timed.h
index 297fd29971808..15d296208423f 100644
--- a/libcxx/include/__atomic/atomic_sync_timed.h
+++ b/libcxx/include/__atomic/atomic_sync_timed.h
@@ -17,6 +17,7 @@
 #include <__config>
 #include <__memory/addressof.h>
 #include <__thread/poll_with_backoff.h>
+#include <__thread/timed_backoff_policy.h>
 #include <__type_traits/conjunction.h>
 #include <__type_traits/decay.h>
 #include <__type_traits/has_unique_object_representation.h>
diff --git a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index 9b31c5d13eab9..ff28632e1c4f3 100644
--- a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1308,6 +1308,7 @@
 {'is_defined': True, 'name': '__ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__114__num_get_base13__int_chr_cntE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__114__num_get_base5__srcE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__114__num_put_base14__format_floatEPcPKcj', 'type': 'FUNC'}
@@ -1587,7 +1588,9 @@
 {'is_defined': True, 'name': '__ZNSt3__132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__133__atomic_wait_native_with_timeoutILm8EEEvPKvS2_y', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__139__atomic_wait_global_table_with_timeoutEPKvxy', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__13cinE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__13pmr15memory_resourceD0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__13pmr15memory_resourceD1Ev', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
index 3e16e595874fe..156b49c10a112 100644
--- a/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1094,6 +1094,7 @@
 {'is_defined': True, 'name': '_ZNSt6__ndk115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEEC2EOS5_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115future_categoryEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcE6__initEPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcEC1EPKcj', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEj', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcEC2EPKcj', 'type': 'FUNC'}
@@ -1101,6 +1102,7 @@
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcED0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcED1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcED2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIwE6__initEPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIwEC1EPKcj', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIwEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEj', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIwEC2EPKcj', 'type': 'FUNC'}
@@ -1223,7 +1225,9 @@
 {'is_defined': True, 'name': '_ZNSt6__ndk132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk133__atomic_wait_native_with_timeoutILj4EEEvPKvS2_y', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk134__construct_barrier_algorithm_baseERi', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk139__atomic_wait_global_table_with_timeoutEPKviy', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk13cinE', 'size': 148, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt6__ndk13pmr15memory_resourceD0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk13pmr15memory_resourceD1Ev', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index b7987c0cdc1eb..55fa373acbcd8 100644
--- a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -453,6 +453,7 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115__thread_structD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115__thread_structD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115future_categoryEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcE6__initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC1EPKcm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC2EPKcm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -460,6 +461,7 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwE6__initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC1EPKcm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC2EPKcm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -571,6 +573,7 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_one_global_tableEPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__139__atomic_wait_global_table_with_timeoutEPKviy', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13cinE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -1713,6 +1716,7 @@
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_one_nativeILm4EEEvPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__133__atomic_wait_native_with_timeoutILm4EEEvPKvS2_y', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem16_FilesystemClock9is_steadyE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem4path19preferred_separatorE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__16__sortIRNS_6__lessIaaEEPaEEvT0_S5_T_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index bdbee9a3e7089..9f4221dd63c43 100644
--- a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -453,6 +453,7 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115__thread_structD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115__thread_structD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115future_categoryEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcE6__initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC1EPKcm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC2EPKcm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -460,6 +461,7 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwE6__initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC1EPKcm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC2EPKcm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -571,6 +573,7 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_one_global_tableEPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__139__atomic_wait_global_table_with_timeoutEPKvlm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13cinE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -1713,6 +1716,7 @@
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_one_nativeILm8EEEvPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__133__atomic_wait_native_with_timeoutILm8EEEvPKvS2_m', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem16_FilesystemClock9is_steadyE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem4path19preferred_separatorE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__16__sortIRNS_6__lessIaaEEPaEEvT0_S5_T_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
index d39dc09984ab7..486176e0bdaa1 100644
--- a/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1094,6 +1094,7 @@
 {'is_defined': True, 'name': '_ZNSt6__ndk115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEEC2EOS5_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115future_categoryEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcE6__initEPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcEC1EPKcm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcEC2EPKcm', 'type': 'FUNC'}
@@ -1101,6 +1102,7 @@
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcED0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcED1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcED2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIwE6__initEPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIwEC1EPKcm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIwEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIwEC2EPKcm', 'type': 'FUNC'}
@@ -1223,7 +1225,9 @@
 {'is_defined': True, 'name': '_ZNSt6__ndk132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk133__atomic_wait_native_with_timeoutILm4EEEvPKvS2_m', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk139__atomic_wait_global_table_with_timeoutEPKvim', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk13cinE', 'size': 280, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt6__ndk13pmr15memory_resourceD0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk13pmr15memory_resourceD1Ev', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
index e17e111cb5644..da2c2246a0e82 100644
--- a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1108,6 +1108,7 @@
 {'is_defined': True, 'name': '_ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEEC2EOS5_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115future_categoryEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcE6__initEPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC1EPKcm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC2EPKcm', 'type': 'FUNC'}
@@ -1115,6 +1116,7 @@
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwE6__initEPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC1EPKcm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC2EPKcm', 'type': 'FUNC'}
@@ -1237,7 +1239,9 @@
 {'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__133__atomic_wait_native_with_timeoutILm8EEEvPKvS2_m', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__139__atomic_wait_global_table_with_timeoutEPKvlm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__13cinE', 'size': 400, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD1Ev', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
index e9f1cc5172ee5..5a39991702719 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1106,6 +1106,7 @@
 {'is_defined': True, 'name': '_ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEEC2EOS5_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115future_categoryEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcE6__initEPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC1EPKcm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC2EPKcm', 'type': 'FUNC'}
@@ -1113,6 +1114,7 @@
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwE6__initEPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC1EPKcm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC2EPKcm', 'type': 'FUNC'}
@@ -1235,7 +1237,9 @@
 {'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__133__atomic_wait_native_with_timeoutILm4EEEvPKvS2_m', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__139__atomic_wait_global_table_with_timeoutEPKvim', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__13cinE', 'size': 280, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD1Ev', 'type': 'FUNC'}

>From 69b421033b1b0ac5af9cdf34bd3f9b76a5c216bd Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sat, 17 Jan 2026 14:13:00 +0000
Subject: [PATCH 07/13] test

---
 .../lost_wakeup.timed2.pass.cpp               | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 libcxx/test/std/thread/thread.semaphore/lost_wakeup.timed2.pass.cpp

diff --git a/libcxx/test/std/thread/thread.semaphore/lost_wakeup.timed2.pass.cpp b/libcxx/test/std/thread/thread.semaphore/lost_wakeup.timed2.pass.cpp
new file mode 100644
index 0000000000000..f75b40636aa03
--- /dev/null
+++ b/libcxx/test/std/thread/thread.semaphore/lost_wakeup.timed2.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-threads
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <semaphore>
+
+// Test that counting_semaphore::try_acquire_for does not suffer from lost wakeup
+// under stress testing.
+
+#include <barrier>
+#include <chrono>
+#include <semaphore>
+#include <thread>
+#include <vector>
+
+int main(int, char**) {
+  std::counting_semaphore<> s(0);
+  (void)s.try_acquire_for(std::chrono::seconds(300));
+
+  return 0;
+}

>From 4e3656c67fe2e78ced0b8ec88ab89cbe90af4f9a Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sat, 17 Jan 2026 14:19:29 +0000
Subject: [PATCH 08/13] freebsd

---
 libcxx/src/atomic.cpp | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp
index 4ac9bdb4c01cb..c68df1a3b7224 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -135,12 +135,17 @@ static void __platform_wait_on_address(void const* __ptr, void const* __val, uin
     std::memcpy(&buffer, const_cast<const void*>(__val), _Size);
     _umtx_op(const_cast<void*>(__ptr), UMTX_OP_WAIT, *reinterpret_cast<__cxx_contention_t*>(&buffer), nullptr, nullptr);
   } else {
-    // TODO the doc says it supports timeout but does not say how to use it
-    // https://man.freebsd.org/cgi/man.cgi?query=_umtx_op
-    __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));
+    _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
   }
 }
 

>From f8597ebc11da5693b0eeb6b3e358fe6486b51f80 Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sat, 17 Jan 2026 14:49:52 +0000
Subject: [PATCH 09/13] abi

---
 ...nux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist | 2 --
 ...werpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist | 2 --
 ...rpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist | 2 --
 ...nux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist | 2 --
 ...known-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist | 4 +---
 ...own-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist | 4 +---
 libcxx/src/atomic.cpp                                         | 4 ++--
 7 files changed, 4 insertions(+), 16 deletions(-)

diff --git a/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
index 156b49c10a112..abbcc5c14b544 100644
--- a/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1094,7 +1094,6 @@
 {'is_defined': True, 'name': '_ZNSt6__ndk115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEEC2EOS5_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115future_categoryEv', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcE6__initEPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcEC1EPKcj', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEj', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcEC2EPKcj', 'type': 'FUNC'}
@@ -1102,7 +1101,6 @@
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcED0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcED1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcED2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIwE6__initEPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIwEC1EPKcj', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIwEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEj', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIwEC2EPKcj', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index 55fa373acbcd8..1224f51e17687 100644
--- a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -453,7 +453,6 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115__thread_structD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115__thread_structD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115future_categoryEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
-{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcE6__initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC1EPKcm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC2EPKcm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -461,7 +460,6 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
-{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwE6__initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC1EPKcm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC2EPKcm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index 9f4221dd63c43..934505b18a64b 100644
--- a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -453,7 +453,6 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115__thread_structD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115__thread_structD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115future_categoryEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
-{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcE6__initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC1EPKcm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC2EPKcm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -461,7 +460,6 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
-{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwE6__initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC1EPKcm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC2EPKcm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
index 486176e0bdaa1..6c437f9adea48 100644
--- a/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1094,7 +1094,6 @@
 {'is_defined': True, 'name': '_ZNSt6__ndk115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEEC2EOS5_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115future_categoryEv', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcE6__initEPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcEC1EPKcm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcEC2EPKcm', 'type': 'FUNC'}
@@ -1102,7 +1101,6 @@
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcED0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcED1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIcED2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIwE6__initEPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIwEC1EPKcm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIwEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt6__ndk115numpunct_bynameIwEC2EPKcm', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
index da2c2246a0e82..017b6d33c4262 100644
--- a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1108,7 +1108,6 @@
 {'is_defined': True, 'name': '_ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEEC2EOS5_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115future_categoryEv', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcE6__initEPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC1EPKcm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC2EPKcm', 'type': 'FUNC'}
@@ -1116,7 +1115,6 @@
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwE6__initEPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC1EPKcm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC2EPKcm', 'type': 'FUNC'}
@@ -2030,4 +2028,4 @@
 {'is_defined': True, 'name': '_ZTv0_n24_NSt3__114basic_iostreamIcNS_11char_traitsIcEEED0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZTv0_n24_NSt3__114basic_iostreamIcNS_11char_traitsIcEEED1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZTv0_n24_NSt3__19strstreamD0Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZTv0_n24_NSt3__19strstreamD1Ev', 'type': 'FUNC'}
\ No newline at end of file
+{'is_defined': True, 'name': '_ZTv0_n24_NSt3__19strstreamD1Ev', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
index 5a39991702719..363fa42975b8e 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1106,7 +1106,6 @@
 {'is_defined': True, 'name': '_ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEEC2EOS5_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115future_categoryEv', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcE6__initEPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC1EPKcm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcEC2EPKcm', 'type': 'FUNC'}
@@ -1114,7 +1113,6 @@
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIcED2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwE6__initEPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC1EPKcm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__115numpunct_bynameIwEC2EPKcm', 'type': 'FUNC'}
@@ -2029,4 +2027,4 @@
 {'is_defined': True, 'name': '_ZTv0_n24_NSt3__114basic_iostreamIcNS_11char_traitsIcEEED0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZTv0_n24_NSt3__114basic_iostreamIcNS_11char_traitsIcEEED1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZTv0_n24_NSt3__19strstreamD0Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZTv0_n24_NSt3__19strstreamD1Ev', 'type': 'FUNC'}
\ No newline at end of file
+{'is_defined': True, 'name': '_ZTv0_n24_NSt3__19strstreamD1Ev', 'type': 'FUNC'}
diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp
index c68df1a3b7224..637c971ed8896 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -130,9 +130,9 @@ 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");
+  char buffer[_Size];
+  std::memcpy(&buffer, const_cast<const void*>(__val), _Size);
   if (__timeout_ns == 0) {
-    char buffer[_Size];
-    std::memcpy(&buffer, const_cast<const void*>(__val), _Size);
     _umtx_op(const_cast<void*>(__ptr), UMTX_OP_WAIT, *reinterpret_cast<__cxx_contention_t*>(&buffer), nullptr, nullptr);
   } else {
     _umtx_time ut;

>From 634fd8e6ddd875c0d63435555bebf2c25b7a70e1 Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sun, 18 Jan 2026 10:06:06 +0000
Subject: [PATCH 10/13] more abi

---
 ...4-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist | 3 +--
 ...wn-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist | 2 ++
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index ff28632e1c4f3..da1e340b1d4aa 100644
--- a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1308,7 +1308,6 @@
 {'is_defined': True, 'name': '__ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__114__num_get_base13__int_chr_cntE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__114__num_get_base5__srcE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__114__num_put_base14__format_floatEPcPKcj', 'type': 'FUNC'}
@@ -2653,4 +2652,4 @@
 {'is_defined': True, 'name': '___cxa_vec_new2', 'type': 'I'}
 {'is_defined': True, 'name': '___cxa_vec_new3', 'type': 'I'}
 {'is_defined': True, 'name': '___dynamic_cast', 'type': 'I'}
-{'is_defined': True, 'name': '___gxx_personality_v0', 'type': 'I'}
\ No newline at end of file
+{'is_defined': True, 'name': '___gxx_personality_v0', 'type': 'I'}
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
index 97a99f0601710..cf4668a2dea21 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
@@ -1206,7 +1206,9 @@
 {'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__133__atomic_wait_native_with_timeoutILm4EEEvPKvS2_m', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__139__atomic_wait_global_table_with_timeoutEPKvim', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__13cinE', 'size': 280, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD1Ev', 'type': 'FUNC'}

>From 32e67ef0d026d6fc51b87cb5a4568455e6640dfc Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sun, 18 Jan 2026 10:07:14 +0000
Subject: [PATCH 11/13] remove 300s test

---
 .../lost_wakeup.timed2.pass.cpp               | 28 -------------------
 1 file changed, 28 deletions(-)
 delete mode 100644 libcxx/test/std/thread/thread.semaphore/lost_wakeup.timed2.pass.cpp

diff --git a/libcxx/test/std/thread/thread.semaphore/lost_wakeup.timed2.pass.cpp b/libcxx/test/std/thread/thread.semaphore/lost_wakeup.timed2.pass.cpp
deleted file mode 100644
index f75b40636aa03..0000000000000
--- a/libcxx/test/std/thread/thread.semaphore/lost_wakeup.timed2.pass.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: no-threads
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-// <semaphore>
-
-// Test that counting_semaphore::try_acquire_for does not suffer from lost wakeup
-// under stress testing.
-
-#include <barrier>
-#include <chrono>
-#include <semaphore>
-#include <thread>
-#include <vector>
-
-int main(int, char**) {
-  std::counting_semaphore<> s(0);
-  (void)s.try_acquire_for(std::chrono::seconds(300));
-
-  return 0;
-}

>From f4139cc0e8f1c4a0aefe93836f5a57e39b92dee8 Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sun, 18 Jan 2026 11:41:07 +0000
Subject: [PATCH 12/13] no threads

---
 libcxx/include/__atomic/atomic_sync_timed.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__atomic/atomic_sync_timed.h b/libcxx/include/__atomic/atomic_sync_timed.h
index 15d296208423f..b2205fc25e406 100644
--- a/libcxx/include/__atomic/atomic_sync_timed.h
+++ b/libcxx/include/__atomic/atomic_sync_timed.h
@@ -116,7 +116,7 @@ _LIBCPP_HIDE_FROM_ABI bool __atomic_wait_unless_with_timeout(
   return __poll_result == __poll_with_backoff_results::__poll_success;
 }
 
-#  else // _LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
+#  elif // _LIBCPP_HAS_THREADS
 
 template <class _AtomicWaitable, class _Poll, class _Rep, class _Period>
 _LIBCPP_HIDE_FROM_ABI bool __atomic_wait_unless_with_timeout(

>From dc6c0cf83e164cefdcd2ff6d5acd0b7dbfc917ec Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sun, 18 Jan 2026 12:44:19 +0000
Subject: [PATCH 13/13] no threads ci

---
 libcxx/include/__atomic/atomic_sync_timed.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__atomic/atomic_sync_timed.h b/libcxx/include/__atomic/atomic_sync_timed.h
index b2205fc25e406..7daff73db7ebd 100644
--- a/libcxx/include/__atomic/atomic_sync_timed.h
+++ b/libcxx/include/__atomic/atomic_sync_timed.h
@@ -116,7 +116,7 @@ _LIBCPP_HIDE_FROM_ABI bool __atomic_wait_unless_with_timeout(
   return __poll_result == __poll_with_backoff_results::__poll_success;
 }
 
-#  elif // _LIBCPP_HAS_THREADS
+#  elif _LIBCPP_HAS_THREADS // _LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
 
 template <class _AtomicWaitable, class _Poll, class _Rep, class _Period>
 _LIBCPP_HIDE_FROM_ABI bool __atomic_wait_unless_with_timeout(



More information about the libcxx-commits mailing list