From 66134e8a5f7fc172dcc9124349047bb793affbaa Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Fri, 6 Jan 2017 20:05:40 +0000 Subject: [PATCH] [libc++] Cleanup and document <__threading_support> Summary: This patch attempts to clean up the macro configuration mess in `<__threading_support>`, specifically the mess involving external threading variants. Additionally this patch adds design documentation for `<__threading_support>` and the configuration macros it uses. The primary change in this patch is separating the idea of an "external API" provided by `<__external_threading>` and the idea of having an external threading library. Now `_LIBCPP_HAS_THREAD_API_EXTERNAL` means that libc++ should use `<__external_threading>` and that the header is expected to exist. Additionally the new macro `_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL` is now used to configure for using an "external library" with the default threading API. Reviewers: compnerd, rmaprath Subscribers: smeenai, cfe-commits, mgorny Differential Revision: https://reviews.llvm.org/D28316 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@291275 91177308-0d34-0410-b5e6-96231b3b80d8 --- CMakeLists.txt | 15 ++++++ docs/DesignDocs/ThreadingSupportAPI.rst | 70 +++++++++++++++++++++++++ docs/index.rst | 2 +- include/__config | 8 +-- include/__config_site.in | 1 + include/__threading_support | 57 +++++++------------- lib/CMakeLists.txt | 2 +- test/CMakeLists.txt | 2 +- test/lit.site.cfg.in | 2 +- test/support/external_threads.cpp | 2 +- 10 files changed, 113 insertions(+), 48 deletions(-) create mode 100644 docs/DesignDocs/ThreadingSupportAPI.rst diff --git a/CMakeLists.txt b/CMakeLists.txt index 803e8f717..405e0da4a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -169,6 +169,9 @@ option(LIBCXX_HAS_PTHREAD_API "Ignore auto-detection and force use of pthread AP 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 @@ if(NOT LIBCXX_ENABLE_THREADS) 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_not(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS _LIBCPP_HAS_NO_THRE 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 diff --git a/docs/DesignDocs/ThreadingSupportAPI.rst b/docs/DesignDocs/ThreadingSupportAPI.rst new file mode 100644 index 000000000..77ec6bce1 --- /dev/null +++ b/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. diff --git a/docs/index.rst b/docs/index.rst index 8f21a27fe..9e72ca9d4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -131,7 +131,7 @@ Design Documents DesignDocs/CapturingConfigInfo DesignDocs/ABIVersioning DesignDocs/VisibilityMacros - + DesignDocs/ThreadingSupportAPI * ` design `_ * ` design `_ diff --git a/include/__config b/include/__config index ffd37c1fb..962ada534 100644 --- a/include/__config +++ b/include/__config @@ -891,9 +891,7 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( #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 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( 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 diff --git a/include/__config_site.in b/include/__config_site.in index f2a198688..667b4e94c 100644 --- a/include/__config_site.in +++ b/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 diff --git a/include/__threading_support b/include/__threading_support index b4383b92c..2a0705a96 100644 --- a/include/__threading_support +++ b/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_PTHREAD) || \ - defined(_LIBCPP_HAS_THREAD_API_EXTERNAL_PTHREAD) -#include -#include -#endif - #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) +# include <__external_threading> +#elif !defined(_LIBCPP_HAS_NO_THREADS) + +#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) +# include +# include +#endif + +#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 @@ void *__libcpp_tls_get(__libcpp_tls_key __key); _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 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p) #endif // _LIBCPP_HAS_THREAD_API_PTHREAD +#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL + _LIBCPP_END_NAMESPACE_STD -#endif // !_LIBCPP_HAS_THREAD_API_EXTERNAL || !__libcpp_has_include(<__external_threading>) - -#endif // _LIBCPP_HAS_NO_THREADS +#endif // !_LIBCPP_HAS_NO_THREADS #endif // _LIBCPP_THREADING_SUPPORT diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 41b9ced3f..cc3ed16b9 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -275,7 +275,7 @@ if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY) ) 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) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d174ec72c..ad110fbfb 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -34,7 +34,7 @@ pythonize_bool(LIBCXXABI_ENABLE_SHARED) 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. diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in index c89af09dd..0cccffcf5 100644 --- a/test/lit.site.cfg.in +++ b/test/lit.site.cfg.in @@ -28,7 +28,7 @@ config.has_libatomic = "@LIBCXX_HAS_ATOMIC_LIB@" 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 diff --git a/test/support/external_threads.cpp b/test/support/external_threads.cpp index 68ba96ff8..019ab473a 100644 --- a/test/support/external_threads.cpp +++ b/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>