[libcxx-commits] [libcxxabi] [libcxx] [libc++] Split the monolithic __threading_support header (PR #79654)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Jan 26 14:10:17 PST 2024
https://github.com/ldionne updated https://github.com/llvm/llvm-project/pull/79654
>From 7c2838a311244743aeff7603e4fd8c07ea2e0ea2 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Fri, 26 Jan 2024 16:00:28 -0500
Subject: [PATCH] [libc++] Split the monolithic __threading_support header
The <__threading_support> header is a huge beast and it's really
difficult to navigate. I find myself struggling to find what I want
every time I have to open it, and I've been considering splitting it
up for years for that reason.
This patch aims not to contain any functional change. The various
implementations of the threading base are simply moved to separate
headers and then the individual headers are simplified in mechanical
ways. For example, we used to have redundant declarations of all the
functions at the top of `__threading_support`, and those are removed
since they are not needed anymore. The various #ifdefs are also
simplified and removed when they become unnecessary.
Finally, this patch adds documentation for the API we expect from
any threading implementation.
---
.../docs/DesignDocs/ThreadingSupportAPI.rst | 14 +-
libcxx/include/CMakeLists.txt | 6 +-
libcxx/include/__atomic/atomic_flag.h | 2 +-
libcxx/include/__atomic/atomic_sync.h | 2 +-
.../__condition_variable/condition_variable.h | 2 +-
libcxx/include/__mutex/mutex.h | 2 +-
libcxx/include/__thread/formatter.h | 2 +-
libcxx/include/__thread/id.h | 2 +-
libcxx/include/__thread/jthread.h | 2 +-
libcxx/include/__thread/support.h | 118 +++++
libcxx/include/__thread/support/c11.h | 190 ++++++++
libcxx/include/__thread/support/external.h | 21 +
libcxx/include/__thread/support/pthread.h | 219 +++++++++
libcxx/include/__thread/support/windows.h | 133 +++++
libcxx/include/__thread/this_thread.h | 2 +-
libcxx/include/__thread/thread.h | 2 +-
.../include/__thread/timed_backoff_policy.h | 2 +-
libcxx/include/__threading_support | 456 ------------------
libcxx/include/libcxx.imp | 20 +
libcxx/include/module.modulemap.in | 12 +-
libcxx/include/mutex | 2 +-
libcxx/include/semaphore | 2 +-
libcxx/include/thread | 2 +-
libcxx/src/call_once.cpp | 2 +-
libcxx/src/condition_variable_destructor.cpp | 2 +-
libcxx/src/mutex_destructor.cpp | 2 +-
libcxx/src/support/win32/thread_win32.cpp | 2 +-
libcxx/utils/generate_iwyu_mapping.py | 2 +-
libcxx/utils/libcxx/test/modules.py | 1 -
libcxxabi/src/cxa_exception_storage.cpp | 2 +-
libcxxabi/src/cxa_guard_impl.h | 2 +-
libcxxabi/src/cxa_thread_atexit.cpp | 2 +-
libcxxabi/src/fallback_malloc.cpp | 2 +-
libcxxabi/test/test_fallback_malloc.pass.cpp | 2 +-
34 files changed, 746 insertions(+), 490 deletions(-)
create mode 100644 libcxx/include/__thread/support.h
create mode 100644 libcxx/include/__thread/support/c11.h
create mode 100644 libcxx/include/__thread/support/external.h
create mode 100644 libcxx/include/__thread/support/pthread.h
create mode 100644 libcxx/include/__thread/support/windows.h
delete mode 100644 libcxx/include/__threading_support
diff --git a/libcxx/docs/DesignDocs/ThreadingSupportAPI.rst b/libcxx/docs/DesignDocs/ThreadingSupportAPI.rst
index 752a9d4d770a1c7..e7f3de54e6782a7 100644
--- a/libcxx/docs/DesignDocs/ThreadingSupportAPI.rst
+++ b/libcxx/docs/DesignDocs/ThreadingSupportAPI.rst
@@ -14,9 +14,9 @@ These different models provide entirely different interfaces from each
other. To address this libc++ wraps the underlying threading API in a new and
consistent API, which it uses internally to implement threading primitives.
-The ``<__threading_support>`` header is where libc++ defines its internal
-threading interface. It contains forward declarations of the internal threading
-interface as well as definitions for the interface.
+The ``<__thread/support.h>`` header is where libc++ defines its internal
+threading interface. It documents the functions and declarations required
+to fullfil the internal threading interface.
External Threading API and the ``<__external_threading>`` header
================================================================
@@ -25,10 +25,10 @@ In order to support vendors with custom threading API's libc++ allows the
entire internal threading interface to be provided by an external,
vendor provided, header.
-When ``_LIBCPP_HAS_THREAD_API_EXTERNAL`` is defined the ``<__threading_support>``
+When ``_LIBCPP_HAS_THREAD_API_EXTERNAL`` is defined the ``<__thread/support.h>``
header simply forwards to the ``<__external_threading>`` header (which must exist).
It is expected that the ``<__external_threading>`` header provide the exact
-interface normally provided by ``<__threading_support>``.
+interface normally provided by ``<__thread/support.h>``.
External Threading Library
==========================
@@ -58,6 +58,10 @@ Threading Configuration Macros
This macro is defined when libc++ should use POSIX threads to implement the
internal threading API.
+**_LIBCPP_HAS_THREAD_API_C11**
+ This macro is defined when libc++ should use C11 threads to implement the
+ internal threading API.
+
**_LIBCPP_HAS_THREAD_API_WIN32**
This macro is defined when libc++ should use Win32 threads to implement the
internal threading API.
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index ed721d467e94f4c..0bb23710cae8495 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -688,10 +688,14 @@ set(files
__thread/id.h
__thread/jthread.h
__thread/poll_with_backoff.h
+ __thread/support.h
+ __thread/support/c11.h
+ __thread/support/external.h
+ __thread/support/pthread.h
+ __thread/support/windows.h
__thread/this_thread.h
__thread/thread.h
__thread/timed_backoff_policy.h
- __threading_support
__tree
__tuple/make_tuple_types.h
__tuple/pair_like.h
diff --git a/libcxx/include/__atomic/atomic_flag.h b/libcxx/include/__atomic/atomic_flag.h
index d76e5e45c01a029..a45a71835477265 100644
--- a/libcxx/include/__atomic/atomic_flag.h
+++ b/libcxx/include/__atomic/atomic_flag.h
@@ -15,7 +15,7 @@
#include <__atomic/memory_order.h>
#include <__chrono/duration.h>
#include <__config>
-#include <__threading_support>
+#include <__thread/support.h>
#include <cstdint>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/libcxx/include/__atomic/atomic_sync.h b/libcxx/include/__atomic/atomic_sync.h
index 3d20d6a8ce25148..93527958b2e1cee 100644
--- a/libcxx/include/__atomic/atomic_sync.h
+++ b/libcxx/include/__atomic/atomic_sync.h
@@ -17,7 +17,7 @@
#include <__config>
#include <__memory/addressof.h>
#include <__thread/poll_with_backoff.h>
-#include <__threading_support>
+#include <__thread/support.h>
#include <__type_traits/decay.h>
#include <cstring>
diff --git a/libcxx/include/__condition_variable/condition_variable.h b/libcxx/include/__condition_variable/condition_variable.h
index 4d8e590e29db7fb..2b1a817e2dfee69 100644
--- a/libcxx/include/__condition_variable/condition_variable.h
+++ b/libcxx/include/__condition_variable/condition_variable.h
@@ -16,7 +16,7 @@
#include <__mutex/mutex.h>
#include <__mutex/unique_lock.h>
#include <__system_error/system_error.h>
-#include <__threading_support>
+#include <__thread/support.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_floating_point.h>
#include <__utility/move.h>
diff --git a/libcxx/include/__mutex/mutex.h b/libcxx/include/__mutex/mutex.h
index 4423abf62b8b78d..ddc85cf5a00d51d 100644
--- a/libcxx/include/__mutex/mutex.h
+++ b/libcxx/include/__mutex/mutex.h
@@ -10,7 +10,7 @@
#define _LIBCPP___MUTEX_MUTEX_H
#include <__config>
-#include <__threading_support>
+#include <__thread/support.h>
#include <__type_traits/is_nothrow_default_constructible.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/libcxx/include/__thread/formatter.h b/libcxx/include/__thread/formatter.h
index 0454864ce93990a..9b54036dcab36b1 100644
--- a/libcxx/include/__thread/formatter.h
+++ b/libcxx/include/__thread/formatter.h
@@ -43,7 +43,7 @@ struct _LIBCPP_TEMPLATE_VIS formatter<__thread_id, _CharT> {
template <class _FormatContext>
_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(__thread_id __id, _FormatContext& __ctx) const {
- // In __threading_support __libcpp_thread_id is either a
+ // In __thread/support/pthread.h, __libcpp_thread_id is either a
// unsigned long long or a pthread_t.
//
// The type of pthread_t is left unspecified in POSIX so it can be any
diff --git a/libcxx/include/__thread/id.h b/libcxx/include/__thread/id.h
index 83b1d8eceede3b4..d5aef3f860ce276 100644
--- a/libcxx/include/__thread/id.h
+++ b/libcxx/include/__thread/id.h
@@ -14,7 +14,7 @@
#include <__config>
#include <__fwd/hash.h>
#include <__fwd/ostream.h>
-#include <__threading_support>
+#include <__thread/support.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/libcxx/include/__thread/jthread.h b/libcxx/include/__thread/jthread.h
index 2fbc8a36755e962..253e3a935d9b733 100644
--- a/libcxx/include/__thread/jthread.h
+++ b/libcxx/include/__thread/jthread.h
@@ -15,8 +15,8 @@
#include <__functional/invoke.h>
#include <__stop_token/stop_source.h>
#include <__stop_token/stop_token.h>
+#include <__thread/support.h>
#include <__thread/thread.h>
-#include <__threading_support>
#include <__type_traits/decay.h>
#include <__type_traits/is_constructible.h>
#include <__type_traits/is_same.h>
diff --git a/libcxx/include/__thread/support.h b/libcxx/include/__thread/support.h
new file mode 100644
index 000000000000000..b05ee892c5f0f65
--- /dev/null
+++ b/libcxx/include/__thread/support.h
@@ -0,0 +1,118 @@
+// -*- 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_SUPPORT_H
+#define _LIBCPP___THREAD_SUPPORT_H
+
+#include <__config>
+
+#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
+# pragma GCC system_header
+#endif
+
+/*
+
+//
+// The library supports multiple implementations of the basic threading functionality.
+// The following functionality must be provided by any implementation:
+//
+
+using __libcpp_timespec_t = ...;
+
+//
+// Mutex
+//
+using __libcpp_mutex_t = ...;
+#define _LIBCPP_MUTEX_INITIALIZER ...
+
+using __libcpp_recursive_mutex_t = ...;
+
+int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t*);
+_LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t*);
+_LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t*);
+_LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t*);
+int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t*);
+
+_LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_lock(__libcpp_mutex_t*);
+_LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool __libcpp_mutex_trylock(__libcpp_mutex_t*);
+_LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_unlock(__libcpp_mutex_t*);
+int __libcpp_mutex_destroy(__libcpp_mutex_t*);
+
+//
+// Condition Variable
+//
+using __libcpp_condvar_t = ...;
+#define _LIBCPP_CONDVAR_INITIALIZER ...
+
+int __libcpp_condvar_signal(__libcpp_condvar_t*);
+int __libcpp_condvar_broadcast(__libcpp_condvar_t*);
+int __libcpp_condvar_wait(__libcpp_condvar_t*, __libcpp_mutex_t*);
+int __libcpp_condvar_timedwait(__libcpp_condvar_t*, __libcpp_mutex_t*, __libcpp_timespec_t*);
+int __libcpp_condvar_destroy(__libcpp_condvar_t*);
+
+//
+// Execute once
+//
+using __libcpp_exec_once_flag = ...;
+#define _LIBCPP_EXEC_ONCE_INITIALIZER ...
+
+int __libcpp_execute_once(__libcpp_exec_once_flag*, void (*__init_routine)());
+
+//
+// Thread id
+//
+using __libcpp_thread_id = ...;
+
+bool __libcpp_thread_id_equal(__libcpp_thread_id, __libcpp_thread_id);
+bool __libcpp_thread_id_less(__libcpp_thread_id, __libcpp_thread_id);
+
+//
+// Thread
+//
+#define _LIBCPP_NULL_THREAD ...
+using __libcpp_thread_t = ...;
+
+bool __libcpp_thread_isnull(const __libcpp_thread_t*);
+int __libcpp_thread_create(__libcpp_thread_t*, void* (*__func)(void*), void* __arg);
+__libcpp_thread_id __libcpp_thread_get_current_id();
+__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t*);
+int __libcpp_thread_join(__libcpp_thread_t*);
+int __libcpp_thread_detach(__libcpp_thread_t*);
+void __libcpp_thread_yield();
+void __libcpp_thread_sleep_for(const chrono::nanoseconds&);
+
+//
+// Thread local storage
+//
+#define _LIBCPP_TLS_DESTRUCTOR_CC ...
+using __libcpp_tls_key = ...;
+
+int __libcpp_tls_create(__libcpp_tls_key*, void (*__at_exit)(void*));
+void* __libcpp_tls_get(__libcpp_tls_key);
+int __libcpp_tls_set(__libcpp_tls_key, void*);
+
+*/
+
+#if !defined(_LIBCPP_HAS_NO_THREADS)
+
+# if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
+# include <__thread/support/external.h>
+# elif defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
+# include <__thread/support/pthread.h>
+# elif defined(_LIBCPP_HAS_THREAD_API_C11)
+# include <__thread/support/c11.h>
+# elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+# include <__thread/support/windows.h>
+# else
+# error "No threading API was selected"
+# endif
+
+#endif // !_LIBCPP_HAS_NO_THREADS
+
+#endif // _LIBCPP___THREAD_SUPPORT_H
diff --git a/libcxx/include/__thread/support/c11.h b/libcxx/include/__thread/support/c11.h
new file mode 100644
index 000000000000000..44515454d69581e
--- /dev/null
+++ b/libcxx/include/__thread/support/c11.h
@@ -0,0 +1,190 @@
+// -*- 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_SUPPORT_C11_H
+#define _LIBCPP___THREAD_SUPPORT_C11_H
+
+#include <__chrono/convert_to_timespec.h>
+#include <__chrono/duration.h>
+#include <__config>
+#include <ctime>
+#include <threads.h>
+
+#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
+# pragma GCC system_header
+#endif
+
+typedef ::timespec __libcpp_timespec_t;
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+//
+// Mutex
+//
+typedef mtx_t __libcpp_mutex_t;
+// mtx_t is a struct so using {} for initialization is valid.
+#define _LIBCPP_MUTEX_INITIALIZER \
+ {}
+
+typedef mtx_t __libcpp_recursive_mutex_t;
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t* __m) {
+ return mtx_init(__m, mtx_plain | mtx_recursive) == thrd_success ? 0 : EINVAL;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
+__libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t* __m) {
+ return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool
+__libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t* __m) {
+ return mtx_trylock(__m) == thrd_success;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
+__libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t* __m) {
+ return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t* __m) {
+ mtx_destroy(__m);
+ return 0;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_lock(__libcpp_mutex_t* __m) {
+ return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool __libcpp_mutex_trylock(__libcpp_mutex_t* __m) {
+ return mtx_trylock(__m) == thrd_success;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_unlock(__libcpp_mutex_t* __m) {
+ return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_mutex_destroy(__libcpp_mutex_t* __m) {
+ mtx_destroy(__m);
+ return 0;
+}
+
+//
+// Condition Variable
+//
+typedef cnd_t __libcpp_condvar_t;
+// cnd_t is a struct so using {} for initialization is valid.
+#define _LIBCPP_CONDVAR_INITIALIZER \
+ {}
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_condvar_signal(__libcpp_condvar_t* __cv) {
+ return cnd_signal(__cv) == thrd_success ? 0 : EINVAL;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv) {
+ return cnd_broadcast(__cv) == thrd_success ? 0 : EINVAL;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
+__libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m) {
+ return cnd_wait(__cv, __m) == thrd_success ? 0 : EINVAL;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
+__libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts) {
+ int __ec = cnd_timedwait(__cv, __m, __ts);
+ return __ec == thrd_timedout ? ETIMEDOUT : __ec;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv) {
+ cnd_destroy(__cv);
+ return 0;
+}
+
+//
+// Execute once
+//
+typedef ::once_flag __libcpp_exec_once_flag;
+#define _LIBCPP_EXEC_ONCE_INITIALIZER ONCE_FLAG_INIT
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_execute_once(__libcpp_exec_once_flag* flag, void (*init_routine)(void)) {
+ ::call_once(flag, init_routine);
+ return 0;
+}
+
+//
+// Thread id
+//
+typedef thrd_t __libcpp_thread_id;
+
+// Returns non-zero if the thread ids are equal, otherwise 0
+inline _LIBCPP_HIDE_FROM_ABI bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) {
+ return thrd_equal(t1, t2) != 0;
+}
+
+// Returns non-zero if t1 < t2, otherwise 0
+inline _LIBCPP_HIDE_FROM_ABI bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) {
+ return t1 < t2;
+}
+
+//
+// Thread
+//
+#define _LIBCPP_NULL_THREAD 0U
+
+typedef thrd_t __libcpp_thread_t;
+
+inline _LIBCPP_HIDE_FROM_ABI __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t) { return *__t; }
+
+inline _LIBCPP_HIDE_FROM_ABI bool __libcpp_thread_isnull(const __libcpp_thread_t* __t) {
+ return __libcpp_thread_get_id(__t) == 0;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg) {
+ int __ec = thrd_create(__t, reinterpret_cast<thrd_start_t>(__func), __arg);
+ return __ec == thrd_nomem ? ENOMEM : __ec;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI __libcpp_thread_id __libcpp_thread_get_current_id() { return thrd_current(); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_thread_join(__libcpp_thread_t* __t) {
+ return thrd_join(*__t, nullptr) == thrd_success ? 0 : EINVAL;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_thread_detach(__libcpp_thread_t* __t) {
+ return thrd_detach(*__t) == thrd_success ? 0 : EINVAL;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI void __libcpp_thread_yield() { thrd_yield(); }
+
+inline _LIBCPP_HIDE_FROM_ABI void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) {
+ __libcpp_timespec_t __ts = std::__convert_to_timespec<__libcpp_timespec_t>(__ns);
+ thrd_sleep(&__ts, nullptr);
+}
+
+//
+// Thread local storage
+//
+#define _LIBCPP_TLS_DESTRUCTOR_CC /* nothing */
+
+typedef tss_t __libcpp_tls_key;
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*)) {
+ return tss_create(__key, __at_exit) == thrd_success ? 0 : EINVAL;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI void* __libcpp_tls_get(__libcpp_tls_key __key) { return tss_get(__key); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_tls_set(__libcpp_tls_key __key, void* __p) {
+ return tss_set(__key, __p) == thrd_success ? 0 : EINVAL;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___THREAD_SUPPORT_C11_H
diff --git a/libcxx/include/__thread/support/external.h b/libcxx/include/__thread/support/external.h
new file mode 100644
index 000000000000000..d5e212491cfdbd0
--- /dev/null
+++ b/libcxx/include/__thread/support/external.h
@@ -0,0 +1,21 @@
+// -*- 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_SUPPORT_EXTERNAL_H
+#define _LIBCPP___THREAD_SUPPORT_EXTERNAL_H
+
+#include <__config>
+
+#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
+# pragma GCC system_header
+#endif
+
+#include <__external_threading>
+
+#endif // _LIBCPP___THREAD_SUPPORT_EXTERNAL_H
diff --git a/libcxx/include/__thread/support/pthread.h b/libcxx/include/__thread/support/pthread.h
new file mode 100644
index 000000000000000..c129234433ac57f
--- /dev/null
+++ b/libcxx/include/__thread/support/pthread.h
@@ -0,0 +1,219 @@
+// -*- 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_SUPPORT_PTHREAD_H
+#define _LIBCPP___THREAD_SUPPORT_PTHREAD_H
+
+#include <__availability>
+#include <__chrono/convert_to_timespec.h>
+#include <__chrono/duration.h>
+#include <__config>
+#include <__fwd/hash.h>
+#include <ctime>
+#include <errno.h>
+#include <pthread.h>
+#include <sched.h>
+
+#ifdef __MVS__
+# include <__support/ibm/nanosleep.h>
+#endif
+
+// Some platforms require <bits/atomic_wide_counter.h> in order for
+// PTHREAD_COND_INITIALIZER to be expanded. Normally that would come
+// in via <pthread.h>, but it's a non-modular header on those platforms,
+// so libc++'s <math.h> usually absorbs atomic_wide_counter.h into the
+// module with <math.h> and makes atomic_wide_counter.h invisible.
+// Include <math.h> here to work around that.
+#include <math.h>
+
+#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
+# pragma GCC system_header
+#endif
+
+typedef ::timespec __libcpp_timespec_t;
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+//
+// Mutex
+//
+typedef pthread_mutex_t __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
+
+typedef pthread_mutex_t __libcpp_recursive_mutex_t;
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t* __m) {
+ pthread_mutexattr_t __attr;
+ int __ec = pthread_mutexattr_init(&__attr);
+ if (__ec)
+ return __ec;
+ __ec = pthread_mutexattr_settype(&__attr, PTHREAD_MUTEX_RECURSIVE);
+ if (__ec) {
+ pthread_mutexattr_destroy(&__attr);
+ return __ec;
+ }
+ __ec = pthread_mutex_init(__m, &__attr);
+ if (__ec) {
+ pthread_mutexattr_destroy(&__attr);
+ return __ec;
+ }
+ __ec = pthread_mutexattr_destroy(&__attr);
+ if (__ec) {
+ pthread_mutex_destroy(__m);
+ return __ec;
+ }
+ return 0;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
+__libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t* __m) {
+ return pthread_mutex_lock(__m);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool
+__libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t* __m) {
+ return pthread_mutex_trylock(__m) == 0;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
+__libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t* __m) {
+ return pthread_mutex_unlock(__m);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t* __m) {
+ return pthread_mutex_destroy(__m);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_lock(__libcpp_mutex_t* __m) {
+ return pthread_mutex_lock(__m);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool __libcpp_mutex_trylock(__libcpp_mutex_t* __m) {
+ return pthread_mutex_trylock(__m) == 0;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_unlock(__libcpp_mutex_t* __m) {
+ return pthread_mutex_unlock(__m);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_mutex_destroy(__libcpp_mutex_t* __m) { return pthread_mutex_destroy(__m); }
+
+//
+// Condition Variable
+//
+typedef pthread_cond_t __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_condvar_signal(__libcpp_condvar_t* __cv) { return pthread_cond_signal(__cv); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv) {
+ return pthread_cond_broadcast(__cv);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m) {
+ return pthread_cond_wait(__cv, __m);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int
+__libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, __libcpp_timespec_t* __ts) {
+ return pthread_cond_timedwait(__cv, __m, __ts);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv) {
+ return pthread_cond_destroy(__cv);
+}
+
+//
+// Execute once
+//
+typedef pthread_once_t __libcpp_exec_once_flag;
+#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_execute_once(__libcpp_exec_once_flag* __flag, void (*__init_routine)()) {
+ return pthread_once(__flag, __init_routine);
+}
+
+//
+// Thread id
+//
+#if defined(__MVS__)
+typedef unsigned long long __libcpp_thread_id;
+#else
+typedef pthread_t __libcpp_thread_id;
+#endif
+
+// Returns non-zero if the thread ids are equal, otherwise 0
+inline _LIBCPP_HIDE_FROM_ABI bool __libcpp_thread_id_equal(__libcpp_thread_id __t1, __libcpp_thread_id __t2) {
+ return __t1 == __t2;
+}
+
+// Returns non-zero if t1 < t2, otherwise 0
+inline _LIBCPP_HIDE_FROM_ABI bool __libcpp_thread_id_less(__libcpp_thread_id __t1, __libcpp_thread_id __t2) {
+ return __t1 < __t2;
+}
+
+//
+// Thread
+//
+#define _LIBCPP_NULL_THREAD ((__libcpp_thread_t()))
+typedef pthread_t __libcpp_thread_t;
+
+inline _LIBCPP_HIDE_FROM_ABI __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t) {
+#if defined(__MVS__)
+ return __t->__;
+#else
+ return *__t;
+#endif
+}
+
+inline _LIBCPP_HIDE_FROM_ABI bool __libcpp_thread_isnull(const __libcpp_thread_t* __t) {
+ return __libcpp_thread_get_id(__t) == 0;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg) {
+ return pthread_create(__t, nullptr, __func, __arg);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI __libcpp_thread_id __libcpp_thread_get_current_id() {
+ const __libcpp_thread_t __current_thread = pthread_self();
+ return __libcpp_thread_get_id(&__current_thread);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_thread_join(__libcpp_thread_t* __t) { return pthread_join(*__t, nullptr); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_thread_detach(__libcpp_thread_t* __t) { return pthread_detach(*__t); }
+
+inline _LIBCPP_HIDE_FROM_ABI void __libcpp_thread_yield() { sched_yield(); }
+
+inline _LIBCPP_HIDE_FROM_ABI void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) {
+ __libcpp_timespec_t __ts = std::__convert_to_timespec<__libcpp_timespec_t>(__ns);
+ while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR)
+ ;
+}
+
+//
+// Thread local storage
+//
+#define _LIBCPP_TLS_DESTRUCTOR_CC /* nothing */
+
+typedef pthread_key_t __libcpp_tls_key;
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*)) {
+ return pthread_key_create(__key, __at_exit);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI void* __libcpp_tls_get(__libcpp_tls_key __key) { return pthread_getspecific(__key); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_tls_set(__libcpp_tls_key __key, void* __p) {
+ return pthread_setspecific(__key, __p);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___THREAD_SUPPORT_PTHREAD_H
diff --git a/libcxx/include/__thread/support/windows.h b/libcxx/include/__thread/support/windows.h
new file mode 100644
index 000000000000000..16d1f3ba5a3cc2e
--- /dev/null
+++ b/libcxx/include/__thread/support/windows.h
@@ -0,0 +1,133 @@
+// -*- 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_SUPPORT_WINDOWS_H
+#define _LIBCPP___THREAD_SUPPORT_WINDOWS_H
+
+#include <__chrono/duration.h>
+#include <__config>
+#include <ctime>
+
+#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
+# pragma GCC system_header
+#endif
+
+typedef ::timespec __libcpp_timespec_t;
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+//
+// Mutex
+//
+typedef void* __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER 0
+
+#if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__)
+typedef void* __libcpp_recursive_mutex_t[6];
+#elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__)
+typedef void* __libcpp_recursive_mutex_t[5];
+#else
+# error Unsupported architecture
+#endif
+
+_LIBCPP_EXPORTED_FROM_ABI int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t* __m);
+
+_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
+__libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t* __m);
+
+_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool
+__libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t* __m);
+
+_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
+__libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t* __m);
+
+_LIBCPP_EXPORTED_FROM_ABI int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t* __m);
+
+_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_lock(__libcpp_mutex_t* __m);
+
+_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool __libcpp_mutex_trylock(__libcpp_mutex_t* __m);
+
+_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_unlock(__libcpp_mutex_t* __m);
+
+_LIBCPP_EXPORTED_FROM_ABI int __libcpp_mutex_destroy(__libcpp_mutex_t* __m);
+
+//
+// Condition variable
+//
+typedef void* __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER 0
+
+_LIBCPP_EXPORTED_FROM_ABI int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
+
+_LIBCPP_EXPORTED_FROM_ABI int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
+
+_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
+__libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
+
+_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
+__libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, __libcpp_timespec_t* __ts);
+
+_LIBCPP_EXPORTED_FROM_ABI int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
+
+//
+// Execute once
+//
+typedef void* __libcpp_exec_once_flag;
+#define _LIBCPP_EXEC_ONCE_INITIALIZER 0
+
+_LIBCPP_EXPORTED_FROM_ABI int __libcpp_execute_once(__libcpp_exec_once_flag* __flag, void (*__init_routine)());
+
+//
+// Thread id
+//
+typedef long __libcpp_thread_id;
+
+_LIBCPP_EXPORTED_FROM_ABI bool __libcpp_thread_id_equal(__libcpp_thread_id __t1, __libcpp_thread_id __t2);
+
+_LIBCPP_EXPORTED_FROM_ABI bool __libcpp_thread_id_less(__libcpp_thread_id __t1, __libcpp_thread_id __t2);
+
+//
+// Thread
+//
+#define _LIBCPP_NULL_THREAD 0U
+typedef void* __libcpp_thread_t;
+
+_LIBCPP_EXPORTED_FROM_ABI bool __libcpp_thread_isnull(const __libcpp_thread_t* __t);
+
+_LIBCPP_EXPORTED_FROM_ABI int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg);
+
+_LIBCPP_EXPORTED_FROM_ABI __libcpp_thread_id __libcpp_thread_get_current_id();
+
+_LIBCPP_EXPORTED_FROM_ABI __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t);
+
+_LIBCPP_EXPORTED_FROM_ABI int __libcpp_thread_join(__libcpp_thread_t* __t);
+
+_LIBCPP_EXPORTED_FROM_ABI int __libcpp_thread_detach(__libcpp_thread_t* __t);
+
+_LIBCPP_EXPORTED_FROM_ABI void __libcpp_thread_yield();
+
+_LIBCPP_EXPORTED_FROM_ABI void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns);
+
+//
+// Thread local storage
+//
+typedef long __libcpp_tls_key;
+
+#define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall
+
+_LIBCPP_EXPORTED_FROM_ABI int
+__libcpp_tls_create(__libcpp_tls_key* __key, void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*));
+
+_LIBCPP_EXPORTED_FROM_ABI void* __libcpp_tls_get(__libcpp_tls_key __key);
+
+_LIBCPP_EXPORTED_FROM_ABI int __libcpp_tls_set(__libcpp_tls_key __key, void* __p);
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___THREAD_SUPPORT_WINDOWS_H
diff --git a/libcxx/include/__thread/this_thread.h b/libcxx/include/__thread/this_thread.h
index 6fb42533aab7c11..de7eea282c8749a 100644
--- a/libcxx/include/__thread/this_thread.h
+++ b/libcxx/include/__thread/this_thread.h
@@ -16,7 +16,7 @@
#include <__config>
#include <__mutex/mutex.h>
#include <__mutex/unique_lock.h>
-#include <__threading_support>
+#include <__thread/support.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/libcxx/include/__thread/thread.h b/libcxx/include/__thread/thread.h
index 0ecaac1b011beee..28c2e21601ae29e 100644
--- a/libcxx/include/__thread/thread.h
+++ b/libcxx/include/__thread/thread.h
@@ -19,7 +19,7 @@
#include <__mutex/mutex.h>
#include <__system_error/system_error.h>
#include <__thread/id.h>
-#include <__threading_support>
+#include <__thread/support.h>
#include <__utility/forward.h>
#include <tuple>
diff --git a/libcxx/include/__thread/timed_backoff_policy.h b/libcxx/include/__thread/timed_backoff_policy.h
index 525f52b34914e26..838c918a57ef0d4 100644
--- a/libcxx/include/__thread/timed_backoff_policy.h
+++ b/libcxx/include/__thread/timed_backoff_policy.h
@@ -15,7 +15,7 @@
#ifndef _LIBCPP_HAS_NO_THREADS
# include <__chrono/duration.h>
-# include <__threading_support>
+# include <__thread/support.h>
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/libcxx/include/__threading_support b/libcxx/include/__threading_support
deleted file mode 100644
index ea6db4a3d59c1c8..000000000000000
--- a/libcxx/include/__threading_support
+++ /dev/null
@@ -1,456 +0,0 @@
-// -*- 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___THREADING_SUPPORT
-#define _LIBCPP___THREADING_SUPPORT
-
-#include <__availability>
-#include <__chrono/convert_to_timespec.h>
-#include <__chrono/duration.h>
-#include <__config>
-#include <__fwd/hash.h>
-#include <ctime>
-#include <errno.h>
-
-#ifdef __MVS__
-# include <__support/ibm/nanosleep.h>
-#endif
-
-#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
-# pragma GCC system_header
-#endif
-
-#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
-# include <__external_threading>
-#elif !defined(_LIBCPP_HAS_NO_THREADS)
-
-# if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
-// Some platforms require <bits/atomic_wide_counter.h> in order for
-// PTHREAD_COND_INITIALIZER to be expanded. Normally that would come
-// in via <pthread.h>, but it's a non-modular header on those platforms,
-// so libc++'s <math.h> usually absorbs atomic_wide_counter.h into the
-// module with <math.h> and makes atomic_wide_counter.h invisible.
-// Include <math.h> here to work around that.
-# include <math.h>
-
-# include <pthread.h>
-# include <sched.h>
-# elif defined(_LIBCPP_HAS_THREAD_API_C11)
-# include <threads.h>
-# endif
-
-# if defined(_LIBCPP_HAS_THREAD_API_WIN32)
-# define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_EXPORTED_FROM_ABI
-# else
-# define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_HIDE_FROM_ABI
-# endif
-
-typedef ::timespec __libcpp_timespec_t;
-#endif // !defined(_LIBCPP_HAS_NO_THREADS)
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-#if !defined(_LIBCPP_HAS_NO_THREADS)
-
-# if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
-// Mutex
-typedef pthread_mutex_t __libcpp_mutex_t;
-# define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
-
-typedef pthread_mutex_t __libcpp_recursive_mutex_t;
-
-// Condition Variable
-typedef pthread_cond_t __libcpp_condvar_t;
-# define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
-
-// Execute once
-typedef pthread_once_t __libcpp_exec_once_flag;
-# define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
-
-// Thread id
-# if defined(__MVS__)
-typedef unsigned long long __libcpp_thread_id;
-# else
-typedef pthread_t __libcpp_thread_id;
-# endif
-
-// Thread
-# define _LIBCPP_NULL_THREAD ((__libcpp_thread_t()))
-typedef pthread_t __libcpp_thread_t;
-
-// Thread Local Storage
-typedef pthread_key_t __libcpp_tls_key;
-
-# define _LIBCPP_TLS_DESTRUCTOR_CC
-# elif defined(_LIBCPP_HAS_THREAD_API_C11)
-// Mutex
-typedef mtx_t __libcpp_mutex_t;
-// mtx_t is a struct so using {} for initialization is valid.
-# define _LIBCPP_MUTEX_INITIALIZER \
- {}
-
-typedef mtx_t __libcpp_recursive_mutex_t;
-
-// Condition Variable
-typedef cnd_t __libcpp_condvar_t;
-// cnd_t is a struct so using {} for initialization is valid.
-# define _LIBCPP_CONDVAR_INITIALIZER \
- {}
-
-// Execute once
-typedef ::once_flag __libcpp_exec_once_flag;
-# define _LIBCPP_EXEC_ONCE_INITIALIZER ONCE_FLAG_INIT
-
-// Thread id
-typedef thrd_t __libcpp_thread_id;
-
-// Thread
-# define _LIBCPP_NULL_THREAD 0U
-
-typedef thrd_t __libcpp_thread_t;
-
-// Thread Local Storage
-typedef tss_t __libcpp_tls_key;
-
-# define _LIBCPP_TLS_DESTRUCTOR_CC
-# elif !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
-// Mutex
-typedef void* __libcpp_mutex_t;
-# define _LIBCPP_MUTEX_INITIALIZER 0
-
-# if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__)
-typedef void* __libcpp_recursive_mutex_t[6];
-# elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__)
-typedef void* __libcpp_recursive_mutex_t[5];
-# else
-# error Unsupported architecture
-# endif
-
-// Condition Variable
-typedef void* __libcpp_condvar_t;
-# define _LIBCPP_CONDVAR_INITIALIZER 0
-
-// Execute Once
-typedef void* __libcpp_exec_once_flag;
-# define _LIBCPP_EXEC_ONCE_INITIALIZER 0
-
-// Thread ID
-typedef long __libcpp_thread_id;
-
-// Thread
-# define _LIBCPP_NULL_THREAD 0U
-
-typedef void* __libcpp_thread_t;
-
-// Thread Local Storage
-typedef long __libcpp_tls_key;
-
-# define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall
-# endif // !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
-
-# if !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
-// Mutex
-_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t* __m);
-
-_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
-__libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t* __m);
-
-_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool
-__libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t* __m);
-
-_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
-__libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t* __m);
-
-_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t* __m);
-
-_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_lock(__libcpp_mutex_t* __m);
-
-_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool __libcpp_mutex_trylock(__libcpp_mutex_t* __m);
-
-_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_unlock(__libcpp_mutex_t* __m);
-
-_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_mutex_destroy(__libcpp_mutex_t* __m);
-
-// Condition variable
-_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
-
-_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
-
-_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
-__libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
-
-_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
-__libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, __libcpp_timespec_t* __ts);
-
-_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
-
-// Execute once
-_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_execute_once(__libcpp_exec_once_flag* __flag, void (*__init_routine)());
-
-// Thread id
-_LIBCPP_THREAD_ABI_VISIBILITY
-bool __libcpp_thread_id_equal(__libcpp_thread_id __t1, __libcpp_thread_id __t2);
-
-_LIBCPP_THREAD_ABI_VISIBILITY
-bool __libcpp_thread_id_less(__libcpp_thread_id __t1, __libcpp_thread_id __t2);
-
-// Thread
-_LIBCPP_THREAD_ABI_VISIBILITY
-bool __libcpp_thread_isnull(const __libcpp_thread_t* __t);
-
-_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg);
-
-_LIBCPP_THREAD_ABI_VISIBILITY
-__libcpp_thread_id __libcpp_thread_get_current_id();
-
-_LIBCPP_THREAD_ABI_VISIBILITY
-__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t);
-
-_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_thread_join(__libcpp_thread_t* __t);
-
-_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_thread_detach(__libcpp_thread_t* __t);
-
-_LIBCPP_THREAD_ABI_VISIBILITY
-void __libcpp_thread_yield();
-
-_LIBCPP_THREAD_ABI_VISIBILITY
-void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns);
-
-// Thread local storage
-_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_tls_create(__libcpp_tls_key* __key, void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*));
-
-_LIBCPP_THREAD_ABI_VISIBILITY
-void* __libcpp_tls_get(__libcpp_tls_key __key);
-
-_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_tls_set(__libcpp_tls_key __key, void* __p);
-
-# endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
-
-# if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
-
-int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t* __m) {
- pthread_mutexattr_t __attr;
- int __ec = pthread_mutexattr_init(&__attr);
- if (__ec)
- return __ec;
- __ec = pthread_mutexattr_settype(&__attr, PTHREAD_MUTEX_RECURSIVE);
- if (__ec) {
- pthread_mutexattr_destroy(&__attr);
- return __ec;
- }
- __ec = pthread_mutex_init(__m, &__attr);
- if (__ec) {
- pthread_mutexattr_destroy(&__attr);
- return __ec;
- }
- __ec = pthread_mutexattr_destroy(&__attr);
- if (__ec) {
- pthread_mutex_destroy(__m);
- return __ec;
- }
- return 0;
-}
-
-int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t* __m) { return pthread_mutex_lock(__m); }
-
-bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t* __m) { return pthread_mutex_trylock(__m) == 0; }
-
-int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t* __m) { return pthread_mutex_unlock(__m); }
-
-int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t* __m) { return pthread_mutex_destroy(__m); }
-
-int __libcpp_mutex_lock(__libcpp_mutex_t* __m) { return pthread_mutex_lock(__m); }
-
-bool __libcpp_mutex_trylock(__libcpp_mutex_t* __m) { return pthread_mutex_trylock(__m) == 0; }
-
-int __libcpp_mutex_unlock(__libcpp_mutex_t* __m) { return pthread_mutex_unlock(__m); }
-
-int __libcpp_mutex_destroy(__libcpp_mutex_t* __m) { return pthread_mutex_destroy(__m); }
-
-// Condition Variable
-int __libcpp_condvar_signal(__libcpp_condvar_t* __cv) { return pthread_cond_signal(__cv); }
-
-int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv) { return pthread_cond_broadcast(__cv); }
-
-int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m) { return pthread_cond_wait(__cv, __m); }
-
-int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, __libcpp_timespec_t* __ts) {
- return pthread_cond_timedwait(__cv, __m, __ts);
-}
-
-int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv) { return pthread_cond_destroy(__cv); }
-
-// Execute once
-int __libcpp_execute_once(__libcpp_exec_once_flag* __flag, void (*__init_routine)()) {
- return pthread_once(__flag, __init_routine);
-}
-
-// Thread id
-// Returns non-zero if the thread ids are equal, otherwise 0
-bool __libcpp_thread_id_equal(__libcpp_thread_id __t1, __libcpp_thread_id __t2) { return __t1 == __t2; }
-
-// Returns non-zero if t1 < t2, otherwise 0
-bool __libcpp_thread_id_less(__libcpp_thread_id __t1, __libcpp_thread_id __t2) { return __t1 < __t2; }
-
-// Thread
-bool __libcpp_thread_isnull(const __libcpp_thread_t* __t) { return __libcpp_thread_get_id(__t) == 0; }
-
-int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg) {
- return pthread_create(__t, nullptr, __func, __arg);
-}
-
-__libcpp_thread_id __libcpp_thread_get_current_id() {
- const __libcpp_thread_t __current_thread = pthread_self();
- return __libcpp_thread_get_id(&__current_thread);
-}
-
-__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t) {
-# if defined(__MVS__)
- return __t->__;
-# else
- return *__t;
-# endif
-}
-
-int __libcpp_thread_join(__libcpp_thread_t* __t) { return pthread_join(*__t, nullptr); }
-
-int __libcpp_thread_detach(__libcpp_thread_t* __t) { return pthread_detach(*__t); }
-
-void __libcpp_thread_yield() { sched_yield(); }
-
-void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) {
- __libcpp_timespec_t __ts = std::__convert_to_timespec<__libcpp_timespec_t>(__ns);
- while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR)
- ;
-}
-
-// Thread local storage
-int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*)) {
- return pthread_key_create(__key, __at_exit);
-}
-
-void* __libcpp_tls_get(__libcpp_tls_key __key) { return pthread_getspecific(__key); }
-
-int __libcpp_tls_set(__libcpp_tls_key __key, void* __p) { return pthread_setspecific(__key, __p); }
-
-# elif defined(_LIBCPP_HAS_THREAD_API_C11)
-
-int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t* __m) {
- return mtx_init(__m, mtx_plain | mtx_recursive) == thrd_success ? 0 : EINVAL;
-}
-
-int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t* __m) {
- return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
-}
-
-bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t* __m) { return mtx_trylock(__m) == thrd_success; }
-
-int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t* __m) {
- return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
-}
-
-int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t* __m) {
- mtx_destroy(__m);
- return 0;
-}
-
-int __libcpp_mutex_lock(__libcpp_mutex_t* __m) { return mtx_lock(__m) == thrd_success ? 0 : EINVAL; }
-
-bool __libcpp_mutex_trylock(__libcpp_mutex_t* __m) { return mtx_trylock(__m) == thrd_success; }
-
-int __libcpp_mutex_unlock(__libcpp_mutex_t* __m) { return mtx_unlock(__m) == thrd_success ? 0 : EINVAL; }
-
-int __libcpp_mutex_destroy(__libcpp_mutex_t* __m) {
- mtx_destroy(__m);
- return 0;
-}
-
-// Condition Variable
-int __libcpp_condvar_signal(__libcpp_condvar_t* __cv) { return cnd_signal(__cv) == thrd_success ? 0 : EINVAL; }
-
-int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv) { return cnd_broadcast(__cv) == thrd_success ? 0 : EINVAL; }
-
-int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m) {
- return cnd_wait(__cv, __m) == thrd_success ? 0 : EINVAL;
-}
-
-int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts) {
- int __ec = cnd_timedwait(__cv, __m, __ts);
- return __ec == thrd_timedout ? ETIMEDOUT : __ec;
-}
-
-int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv) {
- cnd_destroy(__cv);
- return 0;
-}
-
-// Execute once
-int __libcpp_execute_once(__libcpp_exec_once_flag* flag, void (*init_routine)(void)) {
- ::call_once(flag, init_routine);
- return 0;
-}
-
-// Thread id
-// Returns non-zero if the thread ids are equal, otherwise 0
-bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) { return thrd_equal(t1, t2) != 0; }
-
-// Returns non-zero if t1 < t2, otherwise 0
-bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) { return t1 < t2; }
-
-// Thread
-bool __libcpp_thread_isnull(const __libcpp_thread_t* __t) { return __libcpp_thread_get_id(__t) == 0; }
-
-int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg) {
- int __ec = thrd_create(__t, reinterpret_cast<thrd_start_t>(__func), __arg);
- return __ec == thrd_nomem ? ENOMEM : __ec;
-}
-
-__libcpp_thread_id __libcpp_thread_get_current_id() { return thrd_current(); }
-
-__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t) { return *__t; }
-
-int __libcpp_thread_join(__libcpp_thread_t* __t) { return thrd_join(*__t, nullptr) == thrd_success ? 0 : EINVAL; }
-
-int __libcpp_thread_detach(__libcpp_thread_t* __t) { return thrd_detach(*__t) == thrd_success ? 0 : EINVAL; }
-
-void __libcpp_thread_yield() { thrd_yield(); }
-
-void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) {
- __libcpp_timespec_t __ts = std::__convert_to_timespec<__libcpp_timespec_t>(__ns);
- thrd_sleep(&__ts, nullptr);
-}
-
-// Thread local storage
-int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*)) {
- return tss_create(__key, __at_exit) == thrd_success ? 0 : EINVAL;
-}
-
-void* __libcpp_tls_get(__libcpp_tls_key __key) { return tss_get(__key); }
-
-int __libcpp_tls_set(__libcpp_tls_key __key, void* __p) { return tss_set(__key, __p) == thrd_success ? 0 : EINVAL; }
-
-# endif
-
-#endif // !_LIBCPP_HAS_NO_THREADS
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___THREADING_SUPPORT
diff --git a/libcxx/include/libcxx.imp b/libcxx/include/libcxx.imp
index 45fa4a9541917f9..13c0dfeb2bc98f5 100644
--- a/libcxx/include/libcxx.imp
+++ b/libcxx/include/libcxx.imp
@@ -662,6 +662,26 @@
{ include: [ "<__thread/id.h>", "private", "<thread>", "public" ] },
{ include: [ "<__thread/jthread.h>", "private", "<thread>", "public" ] },
{ include: [ "<__thread/poll_with_backoff.h>", "private", "<thread>", "public" ] },
+ { include: [ "<__thread/support.h>", "private", "<atomic>", "public" ] },
+ { include: [ "<__thread/support.h>", "private", "<mutex>", "public" ] },
+ { include: [ "<__thread/support.h>", "private", "<semaphore>", "public" ] },
+ { include: [ "<__thread/support.h>", "private", "<thread>", "public" ] },
+ { include: [ "<__thread/support/c11.h>", "private", "<atomic>", "public" ] },
+ { include: [ "<__thread/support/c11.h>", "private", "<mutex>", "public" ] },
+ { include: [ "<__thread/support/c11.h>", "private", "<semaphore>", "public" ] },
+ { include: [ "<__thread/support/c11.h>", "private", "<thread>", "public" ] },
+ { include: [ "<__thread/support/external.h>", "private", "<atomic>", "public" ] },
+ { include: [ "<__thread/support/external.h>", "private", "<mutex>", "public" ] },
+ { include: [ "<__thread/support/external.h>", "private", "<semaphore>", "public" ] },
+ { include: [ "<__thread/support/external.h>", "private", "<thread>", "public" ] },
+ { include: [ "<__thread/support/pthread.h>", "private", "<atomic>", "public" ] },
+ { include: [ "<__thread/support/pthread.h>", "private", "<mutex>", "public" ] },
+ { include: [ "<__thread/support/pthread.h>", "private", "<semaphore>", "public" ] },
+ { include: [ "<__thread/support/pthread.h>", "private", "<thread>", "public" ] },
+ { include: [ "<__thread/support/windows.h>", "private", "<atomic>", "public" ] },
+ { include: [ "<__thread/support/windows.h>", "private", "<mutex>", "public" ] },
+ { include: [ "<__thread/support/windows.h>", "private", "<semaphore>", "public" ] },
+ { include: [ "<__thread/support/windows.h>", "private", "<thread>", "public" ] },
{ include: [ "<__thread/this_thread.h>", "private", "<thread>", "public" ] },
{ include: [ "<__thread/thread.h>", "private", "<thread>", "public" ] },
{ include: [ "<__thread/timed_backoff_policy.h>", "private", "<thread>", "public" ] },
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 194a74a1e07b145..207b44b6444bf65 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -614,10 +614,6 @@ module std_private_std_mbstate_t [system] {
header "__std_mbstate_t.h"
export *
}
-module std_private_threading_support [system] {
- header "__threading_support"
- export *
-}
module std_private_tree [system] {
header "__tree"
export *
@@ -1773,6 +1769,14 @@ module std_private_thread_jthread [system] {
export *
}
module std_private_thread_poll_with_backoff [system] { header "__thread/poll_with_backoff.h" }
+module std_private_thread_support [system] {
+ header "__thread/support.h"
+ export *
+}
+module std_private_thread_support_c11 [system] { textual header "__thread/support/c11.h" }
+module std_private_thread_support_external [system] { textual header "__thread/support/external.h" }
+module std_private_thread_support_pthread [system] { textual header "__thread/support/pthread.h" }
+module std_private_thread_support_windows [system] { textual header "__thread/support/windows.h" }
module std_private_thread_this_thread [system] { header "__thread/this_thread.h" }
module std_private_thread_thread [system] {
header "__thread/thread.h"
diff --git a/libcxx/include/mutex b/libcxx/include/mutex
index a16ef589c6970be..e67135fc0ec04ef 100644
--- a/libcxx/include/mutex
+++ b/libcxx/include/mutex
@@ -198,7 +198,7 @@ template<class Callable, class ...Args>
#include <__mutex/tag_types.h>
#include <__mutex/unique_lock.h>
#include <__thread/id.h>
-#include <__threading_support>
+#include <__thread/support.h>
#include <__utility/forward.h>
#include <cstddef>
#include <limits>
diff --git a/libcxx/include/semaphore b/libcxx/include/semaphore
index ac3d2d7fe02e881..649705f45b049ce 100644
--- a/libcxx/include/semaphore
+++ b/libcxx/include/semaphore
@@ -58,8 +58,8 @@ using binary_semaphore = counting_semaphore<1>;
#include <__availability>
#include <__chrono/time_point.h>
#include <__thread/poll_with_backoff.h>
+#include <__thread/support.h>
#include <__thread/timed_backoff_policy.h>
-#include <__threading_support>
#include <cstddef>
#include <limits>
#include <version>
diff --git a/libcxx/include/thread b/libcxx/include/thread
index 84c80d04cf03c99..29c7e86785cde48 100644
--- a/libcxx/include/thread
+++ b/libcxx/include/thread
@@ -96,9 +96,9 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
#include <__availability>
#include <__thread/formatter.h>
#include <__thread/jthread.h>
+#include <__thread/support.h>
#include <__thread/this_thread.h>
#include <__thread/thread.h>
-#include <__threading_support>
#include <version>
// standard-mandated includes
diff --git a/libcxx/src/call_once.cpp b/libcxx/src/call_once.cpp
index b596518a65401af..5744347f84b20cd 100644
--- a/libcxx/src/call_once.cpp
+++ b/libcxx/src/call_once.cpp
@@ -10,7 +10,7 @@
#include <__utility/exception_guard.h>
#ifndef _LIBCPP_HAS_NO_THREADS
-# include <__threading_support>
+# include <__thread/support.h>
#endif
#include "include/atomic_support.h"
diff --git a/libcxx/src/condition_variable_destructor.cpp b/libcxx/src/condition_variable_destructor.cpp
index 8b62d4184018e73..59811ed7ff3564a 100644
--- a/libcxx/src/condition_variable_destructor.cpp
+++ b/libcxx/src/condition_variable_destructor.cpp
@@ -12,7 +12,7 @@
// definition is only provided for ABI compatibility.
#include <__config>
-#include <__threading_support>
+#include <__thread/support.h>
#if _LIBCPP_ABI_VERSION == 1 || !defined(_LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION)
# define NEEDS_CONDVAR_DESTRUCTOR
diff --git a/libcxx/src/mutex_destructor.cpp b/libcxx/src/mutex_destructor.cpp
index d5ac257f94d5310..a6ceaaaf23ffed5 100644
--- a/libcxx/src/mutex_destructor.cpp
+++ b/libcxx/src/mutex_destructor.cpp
@@ -17,7 +17,7 @@
// _LIBCPP_BUILDING_LIBRARY to change the definition in the headers.
#include <__config>
-#include <__threading_support>
+#include <__thread/support.h>
#if _LIBCPP_ABI_VERSION == 1 || !defined(_LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION)
# define NEEDS_MUTEX_DESTRUCTOR
diff --git a/libcxx/src/support/win32/thread_win32.cpp b/libcxx/src/support/win32/thread_win32.cpp
index 8736a532073b4b1..a2585c0b89f287d 100644
--- a/libcxx/src/support/win32/thread_win32.cpp
+++ b/libcxx/src/support/win32/thread_win32.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include <__threading_support>
+#include <__thread/support/windows.h>
#include <chrono>
#define NOMINMAX
diff --git a/libcxx/utils/generate_iwyu_mapping.py b/libcxx/utils/generate_iwyu_mapping.py
index fd669172e29ab50..0a650250e747f60 100644
--- a/libcxx/utils/generate_iwyu_mapping.py
+++ b/libcxx/utils/generate_iwyu_mapping.py
@@ -30,7 +30,7 @@ def IWYU_mapping(header: str) -> typing.Optional[typing.List[str]]:
return ["map", "set", "unordered_map", "unordered_set"]
elif header == "__split_buffer":
return ["deque", "vector"]
- elif header == "__threading_support":
+ elif re.match("(__thread/support[.]h)|(__thread/support/.+)", header):
return ["atomic", "mutex", "semaphore", "thread"]
elif header == "__tree":
return ["map", "set"]
diff --git a/libcxx/utils/libcxx/test/modules.py b/libcxx/utils/libcxx/test/modules.py
index 3e9fcae4c5389ae..3f3c7999a1a21d7 100644
--- a/libcxx/utils/libcxx/test/modules.py
+++ b/libcxx/utils/libcxx/test/modules.py
@@ -93,7 +93,6 @@
ExtraHeader = dict()
# locale has a file and not a subdirectory
ExtraHeader["locale"] = "v1/__locale$"
-ExtraHeader["thread"] = "v1/__threading_support$"
ExtraHeader["ranges"] = "v1/__fwd/subrange.h$"
# The extra header is needed since two headers are required to provide the
diff --git a/libcxxabi/src/cxa_exception_storage.cpp b/libcxxabi/src/cxa_exception_storage.cpp
index 3a3233a1b92722f..2479f550e09eff4 100644
--- a/libcxxabi/src/cxa_exception_storage.cpp
+++ b/libcxxabi/src/cxa_exception_storage.cpp
@@ -12,7 +12,7 @@
#include "cxa_exception.h"
-#include <__threading_support>
+#include <__thread/support.h>
#if defined(_LIBCXXABI_HAS_NO_THREADS)
diff --git a/libcxxabi/src/cxa_guard_impl.h b/libcxxabi/src/cxa_guard_impl.h
index e00d54b3a7318ad..7b140d3c3604543 100644
--- a/libcxxabi/src/cxa_guard_impl.h
+++ b/libcxxabi/src/cxa_guard_impl.h
@@ -55,7 +55,7 @@
# endif
#endif
-#include <__threading_support>
+#include <__thread/support.h>
#include <cstdint>
#include <cstring>
#include <limits.h>
diff --git a/libcxxabi/src/cxa_thread_atexit.cpp b/libcxxabi/src/cxa_thread_atexit.cpp
index 665f9e55694abfc..c6bd0aa323f2e15 100644
--- a/libcxxabi/src/cxa_thread_atexit.cpp
+++ b/libcxxabi/src/cxa_thread_atexit.cpp
@@ -8,7 +8,7 @@
#include "abort_message.h"
#include "cxxabi.h"
-#include <__threading_support>
+#include <__thread/support.h>
#ifndef _LIBCXXABI_HAS_NO_THREADS
#if defined(__ELF__) && defined(_LIBCXXABI_LINK_PTHREAD_LIB)
#pragma comment(lib, "pthread")
diff --git a/libcxxabi/src/fallback_malloc.cpp b/libcxxabi/src/fallback_malloc.cpp
index fa802b2d81a7452..76bd2e9bcd9f745 100644
--- a/libcxxabi/src/fallback_malloc.cpp
+++ b/libcxxabi/src/fallback_malloc.cpp
@@ -9,7 +9,7 @@
#include "fallback_malloc.h"
#include "abort_message.h"
-#include <__threading_support>
+#include <__thread/support.h>
#ifndef _LIBCXXABI_HAS_NO_THREADS
#if defined(__ELF__) && defined(_LIBCXXABI_LINK_PTHREAD_LIB)
#pragma comment(lib, "pthread")
diff --git a/libcxxabi/test/test_fallback_malloc.pass.cpp b/libcxxabi/test/test_fallback_malloc.pass.cpp
index 265a7a309e0a989..c8a6a0797510d78 100644
--- a/libcxxabi/test/test_fallback_malloc.pass.cpp
+++ b/libcxxabi/test/test_fallback_malloc.pass.cpp
@@ -11,7 +11,7 @@
#include <cassert>
#include <inttypes.h>
-#include <__threading_support>
+#include <__thread/support.h>
// UNSUPPORTED: c++03
// UNSUPPORTED: modules-build && no-threads
More information about the libcxx-commits
mailing list