[libcxx-commits] [libcxx] [libc++] Introduce a free function __thread_hardware_concurrency() (PR #232284)
Michael G. Kazakov via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Oct 16 04:29:25 PDT 2026
https://github.com/mikekazakov updated https://github.com/llvm/llvm-project/pull/232284
>From ed1b1aca39f64b3b1d237889a4cb402361940358 Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Thu, 15 Oct 2026 12:30:56 +0100
Subject: [PATCH 1/7] Introduce a free function __thread_hardware_concurrency()
---
libcxx/include/CMakeLists.txt | 1 +
libcxx/include/__configuration/availability.h | 6 +++
.../include/__thread/hardware_concurrency.h | 37 ++++++++++++++
libcxx/include/__thread/thread.h | 9 +++-
libcxx/include/module.modulemap.in | 1 +
libcxx/src/thread.cpp | 49 ++++++++++---------
6 files changed, 79 insertions(+), 24 deletions(-)
create mode 100644 libcxx/include/__thread/hardware_concurrency.h
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 9af3d00f36f7e6..0de8b813a1dfb7 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -828,6 +828,7 @@ set(files
__system_error/system_error.h
__system_error/throw_system_error.h
__thread/formatter.h
+ __thread/hardware_concurrency.h
__thread/id.h
__thread/jthread.h
__thread/poll_with_backoff.h
diff --git a/libcxx/include/__configuration/availability.h b/libcxx/include/__configuration/availability.h
index 75d911438e4af1..805a9edab14bbf 100644
--- a/libcxx/include/__configuration/availability.h
+++ b/libcxx/include/__configuration/availability.h
@@ -260,6 +260,12 @@
#endif
+// This controls the availability of the free function std::__thread_hardware_concurrency().
+// It has the same semantics as std::[j]thread::hardware_concurrency(), but allows to query this information
+// without depending on std::thread itself.
+#define _LIBCPP_AVAILABILITY_HAS_HARDWARE_CONCURRENCY_FREE_FUNCTION _LIBCPP_INTRODUCED_IN_LLVM_24
+#define _LIBCPP_AVAILABILITY_HARDWARE_CONCURRENCY_FREE_FUNCTION _LIBCPP_INTRODUCED_IN_LLVM_24_ATTRIBUTE
+
// This controls the availability of the C++26 debugging functions.
// The platform specific implementation is built in the library.
#define _LIBCPP_AVAILABILITY_HAS_DEBUGGING _LIBCPP_INTRODUCED_IN_LLVM_24
diff --git a/libcxx/include/__thread/hardware_concurrency.h b/libcxx/include/__thread/hardware_concurrency.h
new file mode 100644
index 00000000000000..c5ee41686a939c
--- /dev/null
+++ b/libcxx/include/__thread/hardware_concurrency.h
@@ -0,0 +1,37 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___THREAD_HARDWARE_CONCURRENCY_H
+#define _LIBCPP___THREAD_HARDWARE_CONCURRENCY_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+_LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
+
+#if _LIBCPP_HAS_THREADS
+
+[[__nodiscard__]] _LIBCPP_AVAILABILITY_HARDWARE_CONCURRENCY_FREE_FUNCTION
+ _LIBCPP_EXPORTED_FROM_ABI unsigned __thread_hardware_concurrency() _NOEXCEPT;
+
+#endif // _LIBCPP_HAS_THREADS
+
+_LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___THREAD_HARDWARE_CONCURRENCY_H
diff --git a/libcxx/include/__thread/thread.h b/libcxx/include/__thread/thread.h
index 4fd51c12a6dc2b..314fa2d48f6cee 100644
--- a/libcxx/include/__thread/thread.h
+++ b/libcxx/include/__thread/thread.h
@@ -22,6 +22,7 @@
#include <__memory/unique_ptr.h>
#include <__mutex/mutex.h>
#include <__system_error/throw_system_error.h>
+#include <__thread/hardware_concurrency.h>
#include <__thread/id.h>
#include <__thread/support.h>
#include <__type_traits/decay.h>
@@ -262,7 +263,13 @@ class _LIBCPP_EXPORTED_FROM_ABI thread {
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI id get_id() const _NOEXCEPT { return __libcpp_thread_get_id(&__t_); }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() _NOEXCEPT { return __t_; }
- [[__nodiscard__]] static unsigned hardware_concurrency() _NOEXCEPT;
+# if defined(_LIBCPP_BUILDING_LIBRARY) || !_LIBCPP_AVAILABILITY_HAS_HARDWARE_CONCURRENCY_FREE_FUNCTION
+ [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI static unsigned hardware_concurrency() _NOEXCEPT;
+# else
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static unsigned hardware_concurrency() _NOEXCEPT {
+ return std::__thread_hardware_concurrency();
+ }
+# endif
};
inline _LIBCPP_HIDE_FROM_ABI void swap(thread& __x, thread& __y) _NOEXCEPT { __x.swap(__y); }
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 2f6640f8469a5b..460299aea1ed04 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -2202,6 +2202,7 @@ module std {
module thread {
module formatter { header "__thread/formatter.h" }
+ module hardware_concurrency { header "__thread/hardware_concurrency.h" }
module id { header "__thread/id.h" }
module jthread { header "__thread/jthread.h" }
module poll_with_backoff { header "__thread/poll_with_backoff.h" }
diff --git a/libcxx/src/thread.cpp b/libcxx/src/thread.cpp
index 7b0890858e9d64..e931c9288710d1 100644
--- a/libcxx/src/thread.cpp
+++ b/libcxx/src/thread.cpp
@@ -64,29 +64,8 @@ void thread::detach() {
std::__throw_system_error(ec, "thread::detach failed");
}
-unsigned thread::hardware_concurrency() noexcept {
-#if defined(_SC_NPROCESSORS_ONLN)
- long result = sysconf(_SC_NPROCESSORS_ONLN);
- // sysconf returns -1 if the name is invalid, the option does not exist or
- // does not have a definite limit.
- // if sysconf returns some other negative number, we have no idea
- // what is going on. Default to something safe.
- if (result < 0)
- return 0;
- return static_cast<unsigned>(result);
-#elif defined(_WIN32)
- return static_cast<unsigned>(GetActiveProcessorCount(ALL_PROCESSOR_GROUPS));
-#else // defined(CTL_HW) && defined(HW_NCPU)
- // TODO: grovel through /proc or check cpuid on x86 and similar
- // instructions on other architectures.
-# if defined(_LIBCPP_WARNING)
- _LIBCPP_WARNING("hardware_concurrency not yet implemented")
-# else
-# warning hardware_concurrency not yet implemented
-# endif
- return 0; // Means not computable [thread.thread.static]
-#endif // defined(CTL_HW) && defined(HW_NCPU)
-}
+// Defined here only for backwards compatibility
+unsigned thread::hardware_concurrency() noexcept { return __thread_hardware_concurrency(); }
namespace this_thread {
@@ -171,5 +150,29 @@ void __thread_struct::notify_all_at_thread_exit(condition_variable* cv, mutex* m
void __thread_struct::__make_ready_at_thread_exit(__assoc_sub_state* __s) { __p_->__make_ready_at_thread_exit(__s); }
+unsigned __thread_hardware_concurrency() noexcept {
+#if defined(_SC_NPROCESSORS_ONLN)
+ long result = sysconf(_SC_NPROCESSORS_ONLN);
+ // sysconf returns -1 if the name is invalid, the option does not exist or
+ // does not have a definite limit.
+ // if sysconf returns some other negative number, we have no idea
+ // what is going on. Default to something safe.
+ if (result < 0)
+ return 0;
+ return static_cast<unsigned>(result);
+#elif defined(_WIN32)
+ return static_cast<unsigned>(GetActiveProcessorCount(ALL_PROCESSOR_GROUPS));
+#else // defined(CTL_HW) && defined(HW_NCPU)
+ // TODO: grovel through /proc or check cpuid on x86 and similar
+ // instructions on other architectures.
+# if defined(_LIBCPP_WARNING)
+ _LIBCPP_WARNING("hardware_concurrency not yet implemented")
+# else
+# warning hardware_concurrency not yet implemented
+# endif
+ return 0; // Means not computable [thread.thread.static]
+#endif // defined(CTL_HW) && defined(HW_NCPU)
+}
+
_LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS
_LIBCPP_END_NAMESPACE_STD
>From ec805b15beb7aa95e192392746c5729f3cd3f213 Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Thu, 15 Oct 2026 12:50:12 +0100
Subject: [PATCH 2/7] Updating the abilist
---
...nknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist | 1 +
1 file changed, 1 insertion(+)
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 69c32bd5be8775..880cb2504c0843 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
@@ -1234,6 +1234,7 @@
{'is_defined': True, 'name': '_ZNSt3__126__atomic_wait_global_tableEPKvi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__129__thread_hardware_concurrencyEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
{'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'}
>From 8c69b9379f15cfde6fe4a3ee9958ac8936afa4ee Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Thu, 15 Oct 2026 16:02:52 +0100
Subject: [PATCH 3/7] Updated more abilists
---
...m64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist | 1 +
...-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist | 1 +
.../powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist | 1 +
...owerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist | 1 +
...-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist | 1 +
...nown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist | 1 +
6 files changed, 6 insertions(+)
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 74e0af974e4538..186159115eaced 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
@@ -1586,6 +1586,7 @@
{'is_defined': True, 'name': '__ZNSt3__126__atomic_wait_global_tableEPKvx', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__129__thread_hardware_concurrencyEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
{'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'}
diff --git a/libcxx/lib/abi/i686-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/i686-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
index 1b0cd758bfcf36..f423cab70fff68 100644
--- a/libcxx/lib/abi/i686-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/i686-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1223,6 +1223,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk126__atomic_wait_global_tableEPKvi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk129__thread_hardware_concurrencyEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
{'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'}
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 c61db56dc2b904..d121aba28c6626 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
@@ -573,6 +573,7 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__126__atomic_wait_global_tableEPKvi', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__129__thread_hardware_concurrencyEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_all_global_tableEPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_one_global_tableEPKv', '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 7663aa877a096f..69b0833420bc82 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
@@ -573,6 +573,7 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__126__atomic_wait_global_tableEPKvl', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__129__thread_hardware_concurrencyEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_all_global_tableEPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_one_global_tableEPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
index 536614e0ccfa64..cc027ffd7eb0ae 100644
--- a/libcxx/lib/abi/x86_64-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1223,6 +1223,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk126__atomic_wait_global_tableEPKvi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk129__thread_hardware_concurrencyEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
{'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'}
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 b6850b2ec80938..b5187b4ec82d45 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
@@ -1205,6 +1205,7 @@
{'is_defined': True, 'name': '_ZNSt3__126__atomic_wait_global_tableEPKvi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__129__thread_hardware_concurrencyEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
{'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'}
>From 16aa57075de237102c12c83213c138965c8c230d Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Thu, 15 Oct 2026 16:03:16 +0100
Subject: [PATCH 4/7] Don't put _LIBCPP_EXPORTED_FROM_ABI twice
---
libcxx/include/__thread/thread.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/include/__thread/thread.h b/libcxx/include/__thread/thread.h
index 314fa2d48f6cee..89c1fefd654043 100644
--- a/libcxx/include/__thread/thread.h
+++ b/libcxx/include/__thread/thread.h
@@ -264,7 +264,7 @@ class _LIBCPP_EXPORTED_FROM_ABI thread {
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() _NOEXCEPT { return __t_; }
# if defined(_LIBCPP_BUILDING_LIBRARY) || !_LIBCPP_AVAILABILITY_HAS_HARDWARE_CONCURRENCY_FREE_FUNCTION
- [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI static unsigned hardware_concurrency() _NOEXCEPT;
+ [[__nodiscard__]] static unsigned hardware_concurrency() _NOEXCEPT;
# else
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static unsigned hardware_concurrency() _NOEXCEPT {
return std::__thread_hardware_concurrency();
>From f3c4adb82ee5c70e348bc99c1c90eaf529b9b548 Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Thu, 15 Oct 2026 18:25:10 +0100
Subject: [PATCH 5/7] Updated FreeBSD abilist as well
---
...-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist | 1 +
1 file changed, 1 insertion(+)
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 d655541acdc8d5..eb1638841be7a3 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
@@ -1236,6 +1236,7 @@
{'is_defined': True, 'name': '_ZNSt3__126__atomic_wait_global_tableEPKvl', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__129__thread_hardware_concurrencyEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
{'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'}
>From 4d3966111da2f5aafe9cf6fd942f72b287f0f94c Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Fri, 16 Oct 2026 12:13:32 +0100
Subject: [PATCH 6/7] Working around Windows linking issue
---
libcxx/lib/abi/CHANGELOG.TXT | 6 ++++++
...ple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist | 1 +
libcxx/src/thread.cpp | 7 +++++--
3 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/libcxx/lib/abi/CHANGELOG.TXT b/libcxx/lib/abi/CHANGELOG.TXT
index 85d2e596ed51f4..05f4a14540270e 100644
--- a/libcxx/lib/abi/CHANGELOG.TXT
+++ b/libcxx/lib/abi/CHANGELOG.TXT
@@ -16,6 +16,12 @@ New entries should be added directly below the "Version" header.
Version 24.0
------------
+* [libc++] Add <__thread/hardware_concurrency.h> __thread_hardware_concurrency()
+
+ All platforms
+ -------------
+ Symbol added: _ZNSt3__129__thread_hardware_concurrencyEv
+
* [libc++] Remove locale::id::__next_id from the ABI
`__next_id` is only ever used inside the dylib, so we can avoid making it public.
diff --git a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index 00b5949f843acd..e290f961ba6323 100644
--- a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1579,6 +1579,7 @@
{'is_defined': True, 'name': '__ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__127__from_chars_floating_pointEPKcS1_RdNS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__127__from_chars_floating_pointEPKcS1_RfNS_12chars_formatE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__129__thread_hardware_concurrencyEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'}
diff --git a/libcxx/src/thread.cpp b/libcxx/src/thread.cpp
index e931c9288710d1..74fbbf86099ed2 100644
--- a/libcxx/src/thread.cpp
+++ b/libcxx/src/thread.cpp
@@ -64,8 +64,11 @@ void thread::detach() {
std::__throw_system_error(ec, "thread::detach failed");
}
-// Defined here only for backwards compatibility
-unsigned thread::hardware_concurrency() noexcept { return __thread_hardware_concurrency(); }
+// Defined here only for backwards compatibility.
+// No backward compatibility on Windows, since otherwise static-linked libc++ defines this symbol twice.
+if !defined (_WIN32)
+ unsigned thread::hardware_concurrency() noexcept { return __thread_hardware_concurrency(); }
+#endif
namespace this_thread {
>From 44cfee4c8d0ebfef50d7360b74c6ae96a00f4d40 Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Fri, 16 Oct 2026 12:29:07 +0100
Subject: [PATCH 7/7] Typo fix
---
libcxx/src/thread.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/src/thread.cpp b/libcxx/src/thread.cpp
index 74fbbf86099ed2..2b2a3544505fff 100644
--- a/libcxx/src/thread.cpp
+++ b/libcxx/src/thread.cpp
@@ -66,8 +66,8 @@ void thread::detach() {
// Defined here only for backwards compatibility.
// No backward compatibility on Windows, since otherwise static-linked libc++ defines this symbol twice.
-if !defined (_WIN32)
- unsigned thread::hardware_concurrency() noexcept { return __thread_hardware_concurrency(); }
+#if !defined(_WIN32)
+unsigned thread::hardware_concurrency() noexcept { return __thread_hardware_concurrency(); }
#endif
namespace this_thread {
More information about the libcxx-commits
mailing list