Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -169,6 +169,9 @@ option(LIBCXX_HAS_EXTERNAL_THREAD_API "Build libc++ with an externalized threading API. This option may only be set to ON when LIBCXX_ENABLE_THREADS=ON." OFF) +option(LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY + "Build libc++ with an externalized threading library. + This option may only be set to ON when LIBCXX_ENABLE_THREADS=ON" OFF) # Misc options ---------------------------------------------------------------- # FIXME: Turn -pedantic back ON. It is currently off because it warns @@ -230,6 +233,17 @@ message(FATAL_ERROR "LIBCXX_HAS_EXTERNAL_THREAD_API can only be set to ON" " when LIBCXX_ENABLE_THREADS is also set to ON.") endif() + if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY) + message(FATAL_ERROR "LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY can only be set " + "to ON when LIBCXX_ENABLE_THREADS is also set to ON.") + endif() + +endif() + +if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY AND LIBCXX_HAS_EXTERNAL_THREAD_API) + message(FATAL_ERROR "The options LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY and " + "LIBCXX_HAS_EXTERNAL_THREAD_API cannot both be ON at " + "the same time") endif() if(LIBCXX_HAS_PTHREAD_API AND LIBCXX_HAS_EXTERNAL_THREAD_API) @@ -520,6 +534,7 @@ config_define_if(LIBCXX_HAS_PTHREAD_API _LIBCPP_HAS_THREAD_API_PTHREAD) config_define_if(LIBCXX_HAS_EXTERNAL_THREAD_API _LIBCPP_HAS_THREAD_API_EXTERNAL) +config_define_if(LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) config_define_if(LIBCXX_HAS_MUSL_LIBC _LIBCPP_HAS_MUSL_LIBC) # By default libc++ on Windows expects to use a shared library, which requires Index: docs/DesignDocs/ThreadingSupportAPI.rst =================================================================== --- /dev/null +++ docs/DesignDocs/ThreadingSupportAPI.rst @@ -0,0 +1,70 @@ +===================== +Threading Support API +===================== + +.. contents:: + :local: + +Overview +======== + +Libc++ supports using multiple different threading models and configurations +to implement the threading parts of libc++, including ```` and ````. +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. + +External Threading API and the ``<__external_threading>`` header +================================================================ + +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>`` +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>``. + +External Threading Library +========================== + +Normally ``<__threading_support>`` provides inline definitions to each internal +threading API function it declares. However libc++ also supports using an +external library to provide the definitions. + +When ``_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL`` libc++ does not provide inline +definitions for the internal API, instead assuming the definitions will be +provided by an external library. + +Threading Configuration Macros +============================== + +**_LIBCPP_HAS_NO_THREADS** + This macro is defined when libc++ is built without threading support. It + should not be manually defined by the user. + +**_LIBCPP_HAS_THREAD_API_EXTERNAL** + This macro is defined when libc++ should use the ``<__external_threading>`` + header to provide the internal threading API. This macro overrides + ``_LIBCPP_HAS_THREAD_API_PTHREAD``. + +**_LIBCPP_HAS_THREAD_API_PTHREAD** + This macro is defined when libc++ should use POSIX threads to implement the + internal threading API. + +**_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL** + This macro is defined when libc++ expects the definitions of the internal + threading API to be provided by an external library. When defined + ``<__threading_support>`` will only provide the forward declarations and + typedefs for the internal threading API. + +**_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL** + This macro is used to build an external threading library using the + ``<__threading_support>``. Specifically it exposes the threading API + definitions in ``<__threading_support>`` as non-inline definitions meant to + be compiled into a library. Index: docs/index.rst =================================================================== --- docs/index.rst +++ docs/index.rst @@ -131,7 +131,7 @@ DesignDocs/CapturingConfigInfo DesignDocs/ABIVersioning DesignDocs/VisibilityMacros - + DesignDocs/ThreadingSupportAPI * ` design `_ * ` design `_ Index: include/__config =================================================================== --- include/__config +++ include/__config @@ -891,9 +891,7 @@ #endif // Thread API -#if !defined(_LIBCPP_HAS_NO_THREADS) && \ - !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && \ - !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) +#if !defined(_LIBCPP_HAS_NO_THREADS) # if defined(__FreeBSD__) || \ defined(__Fuchsia__) || \ defined(__NetBSD__) || \ @@ -901,7 +899,9 @@ defined(__APPLE__) || \ defined(__CloudABI__) || \ defined(__sun__) -# define _LIBCPP_HAS_THREAD_API_PTHREAD +# ifndef _LIBCPP_HAS_THREAD_API_PTHREAD +# define _LIBCPP_HAS_THREAD_API_PTHREAD +# endif # else # error "No thread API" # endif // _LIBCPP_HAS_THREAD_API Index: include/__config_site.in =================================================================== --- include/__config_site.in +++ include/__config_site.in @@ -21,6 +21,7 @@ #cmakedefine _LIBCPP_HAS_MUSL_LIBC #cmakedefine _LIBCPP_HAS_THREAD_API_PTHREAD #cmakedefine _LIBCPP_HAS_THREAD_API_EXTERNAL +#cmakedefine _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL #cmakedefine _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS #endif // _LIBCPP_CONFIG_SITE Index: include/__threading_support =================================================================== --- include/__threading_support +++ include/__threading_support @@ -17,39 +17,17 @@ #pragma GCC system_header #endif -#ifndef _LIBCPP_HAS_NO_THREADS - -#ifndef __libcpp_has_include - #ifndef __has_include - #define __libcpp_has_include(x) 0 - #else - #define __libcpp_has_include(x) __has_include(x) - #endif -#endif - -#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) && \ - !__libcpp_has_include(<__external_threading>) -// If the <__external_threading> header is absent, build libc++ against a -// pthread-oriented thread api but leave out its implementation. This setup -// allows building+testing of an externally-threaded library variant (on any -// platform that supports pthreads). Here, an 'externally-threaded' library -// variant is one where the implementation of the libc++ thread api is provided -// as a separate library. -#define _LIBCPP_HAS_THREAD_API_EXTERNAL_PTHREAD -#endif - -#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) && \ - __libcpp_has_include(<__external_threading>) -#include <__external_threading> -#else +#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) +# include <__external_threading> +#elif !defined(_LIBCPP_HAS_NO_THREADS) -#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || \ - defined(_LIBCPP_HAS_THREAD_API_EXTERNAL_PTHREAD) -#include -#include +#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) +# include +# include #endif -#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) +#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ + defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) #define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS #else #define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY @@ -57,8 +35,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || \ - defined(_LIBCPP_HAS_THREAD_API_EXTERNAL_PTHREAD) +#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) // Mutex typedef pthread_mutex_t __libcpp_mutex_t; #define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER @@ -175,8 +152,10 @@ _LIBCPP_THREAD_ABI_VISIBILITY int __libcpp_tls_set(__libcpp_tls_key __key, void *__p); -#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || \ - defined(_LIBCPP_BUILDING_THREAD_API_EXTERNAL_PTHREAD) +#if !defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ + defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) + +#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) { @@ -344,10 +323,10 @@ #endif // _LIBCPP_HAS_THREAD_API_PTHREAD -_LIBCPP_END_NAMESPACE_STD +#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL -#endif // !_LIBCPP_HAS_THREAD_API_EXTERNAL || !__libcpp_has_include(<__external_threading>) +_LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP_HAS_NO_THREADS +#endif // !_LIBCPP_HAS_NO_THREADS #endif // _LIBCPP_THREADING_SUPPORT Index: lib/CMakeLists.txt =================================================================== --- lib/CMakeLists.txt +++ lib/CMakeLists.txt @@ -275,7 +275,7 @@ ) endif() -if (LIBCXX_HAS_EXTERNAL_THREAD_API) +if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY) file(GLOB LIBCXX_EXTERNAL_THREADING_SUPPORT_SOURCES ../test/support/external_threads.cpp) if (LIBCXX_ENABLE_SHARED) Index: test/CMakeLists.txt =================================================================== --- test/CMakeLists.txt +++ test/CMakeLists.txt @@ -34,7 +34,7 @@ pythonize_bool(LIBCXXABI_USE_LLVM_UNWINDER) pythonize_bool(LIBCXX_HAS_ATOMIC_LIB) pythonize_bool(LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB) -pythonize_bool(LIBCXX_HAS_EXTERNAL_THREAD_API) +pythonize_bool(LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY) # By default, for non-standalone builds, libcxx and libcxxabi share a library # directory. Index: test/lit.site.cfg.in =================================================================== --- test/lit.site.cfg.in +++ test/lit.site.cfg.in @@ -28,7 +28,7 @@ config.use_libatomic = "@LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB@" config.libcxxabi_shared = "@LIBCXXABI_ENABLE_SHARED@" -config.cxx_ext_threads = "@LIBCXX_HAS_EXTERNAL_THREAD_API@" +config.cxx_ext_threads = "@LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY@" # Let the main config do the real work. config.loaded_site_config = True Index: test/support/external_threads.cpp =================================================================== --- test/support/external_threads.cpp +++ test/support/external_threads.cpp @@ -6,5 +6,5 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#define _LIBCPP_BUILDING_THREAD_API_EXTERNAL_PTHREAD +#define _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL #include <__threading_support>