Skip to content

[libc++] Implement library support for MCF thread model #116550

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion libcxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ endif()
option(LIBCXX_HAS_MUSL_LIBC "Build libc++ with support for the Musl C library" OFF)
option(LIBCXX_HAS_PTHREAD_API "Ignore auto-detection and force use of pthread API" OFF)
option(LIBCXX_HAS_WIN32_THREAD_API "Ignore auto-detection and force use of win32 thread API" OFF)
option(LIBCXX_HAS_MCF_THREAD_API "Ignore auto-detection and force use of mcfgthread API" OFF)
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)
Expand Down Expand Up @@ -342,7 +343,10 @@ if(NOT LIBCXX_ENABLE_THREADS)
message(FATAL_ERROR "LIBCXX_HAS_WIN32_THREAD_API can only be set to ON"
" when LIBCXX_ENABLE_THREADS is also set to ON.")
endif()

if (LIBCXX_HAS_MCF_THREAD_API)
message(FATAL_ERROR "LIBCXX_HAS_MCF_THREAD_API can only be set to ON"
" when LIBCXX_ENABLE_THREADS is also set to ON.")
endif()
endif()

if (LIBCXX_HAS_EXTERNAL_THREAD_API)
Expand All @@ -356,6 +360,11 @@ if (LIBCXX_HAS_EXTERNAL_THREAD_API)
" and LIBCXX_HAS_WIN32_THREAD_API cannot be both"
" set to ON at the same time.")
endif()
if (LIBCXX_HAS_MCF_THREAD_API)
message(FATAL_ERROR "The options LIBCXX_HAS_EXTERNAL_THREAD_API"
" and LIBCXX_HAS_MCF_THREAD_API cannot be both"
" set to ON at the same time.")
endif()
endif()

if (LIBCXX_HAS_PTHREAD_API)
Expand All @@ -364,6 +373,19 @@ if (LIBCXX_HAS_PTHREAD_API)
" and LIBCXX_HAS_WIN32_THREAD_API cannot be both"
" set to ON at the same time.")
endif()
if (LIBCXX_HAS_MCF_THREAD_API)
message(FATAL_ERROR "The options LIBCXX_HAS_PTHREAD_API"
" and LIBCXX_HAS_MCF_THREAD_API cannot be both"
" set to ON at the same time.")
endif()
endif()

if (LIBCXX_HAS_WIN32_THREAD_API)
if (LIBCXX_HAS_MCF_THREAD_API)
message(FATAL_ERROR "The options LIBCXX_HAS_WIN32_THREAD_API"
" and LIBCXX_HAS_MCF_THREAD_API cannot be both"
" set to ON at the same time.")
endif()
endif()

if (NOT LIBCXX_ENABLE_RTTI AND LIBCXX_ENABLE_EXCEPTIONS)
Expand Down Expand Up @@ -754,6 +776,7 @@ endif()
config_define(${LIBCXX_HAS_PTHREAD_API} _LIBCPP_HAS_THREAD_API_PTHREAD)
config_define(${LIBCXX_HAS_EXTERNAL_THREAD_API} _LIBCPP_HAS_THREAD_API_EXTERNAL)
config_define(${LIBCXX_HAS_WIN32_THREAD_API} _LIBCPP_HAS_THREAD_API_WIN32)
config_define(${LIBCXX_HAS_MCF_THREAD_API} _LIBCPP_HAS_THREAD_API_MCF)
config_define(${LIBCXX_HAS_MUSL_LIBC} _LIBCPP_HAS_MUSL_LIBC)
config_define_if(LIBCXX_NO_VCRUNTIME _LIBCPP_NO_VCRUNTIME)
config_define(${LIBCXX_ENABLE_FILESYSTEM} _LIBCPP_HAS_FILESYSTEM)
Expand Down
4 changes: 4 additions & 0 deletions libcxx/docs/DesignDocs/ThreadingSupportAPI.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,7 @@ Threading Configuration Macros
**_LIBCPP_HAS_THREAD_API_WIN32**
This macro is defined when libc++ should use Win32 threads to implement the
internal threading API.

**_LIBCPP_HAS_THREAD_API_MCF**
This macro is defined when libc++ should use the mcfgthread library to
implement the internal threading API.
6 changes: 4 additions & 2 deletions libcxx/include/__config
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,7 @@ typedef __char32_t char32_t;
# if _LIBCPP_HAS_THREADS && \
!_LIBCPP_HAS_THREAD_API_PTHREAD && \
!_LIBCPP_HAS_THREAD_API_WIN32 && \
!_LIBCPP_HAS_THREAD_API_MCF && \
!_LIBCPP_HAS_THREAD_API_EXTERNAL

# if defined(__FreeBSD__) || \
Expand Down Expand Up @@ -882,7 +883,7 @@ typedef __char32_t char32_t;
// clang-format off
# if (_LIBCPP_HAS_THREAD_API_PTHREAD && defined(__GLIBC__)) || \
(_LIBCPP_HAS_THREAD_API_C11 && defined(__Fuchsia__)) || \
_LIBCPP_HAS_THREAD_API_WIN32
_LIBCPP_HAS_THREAD_API_WIN32 || _LIBCPP_HAS_THREAD_API_MCF
// clang-format on
# define _LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION 1
# else
Expand All @@ -897,7 +898,8 @@ typedef __char32_t char32_t;
//
// TODO(EricWF): This is potentially true for some pthread implementations
// as well.
# if (_LIBCPP_HAS_THREAD_API_C11 && defined(__Fuchsia__)) || _LIBCPP_HAS_THREAD_API_WIN32
# if (_LIBCPP_HAS_THREAD_API_C11 && defined(__Fuchsia__)) || \
_LIBCPP_HAS_THREAD_API_WIN32 || _LIBCPP_HAS_THREAD_API_MCF
# define _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION 1
# else
# define _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION 0
Expand Down
1 change: 1 addition & 0 deletions libcxx/include/__config_site.in
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#cmakedefine01 _LIBCPP_HAS_THREAD_API_PTHREAD
#cmakedefine01 _LIBCPP_HAS_THREAD_API_EXTERNAL
#cmakedefine01 _LIBCPP_HAS_THREAD_API_WIN32
#cmakedefine01 _LIBCPP_HAS_THREAD_API_MCF
#define _LIBCPP_HAS_THREAD_API_C11 0 // FIXME: Is this guarding dead code?
#cmakedefine _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS
#cmakedefine01 _LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS
Expand Down
2 changes: 2 additions & 0 deletions libcxx/include/__thread/support.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ _LIBCPP_END_NAMESPACE_STD
# include <__thread/support/c11.h>
# elif _LIBCPP_HAS_THREAD_API_WIN32
# include <__thread/support/windows.h>
# elif defined(_LIBCPP_HAS_THREAD_API_MCF)
# include <mcfgthread/libcxx.h>
# else
# error "No threading API was selected"
# endif
Expand Down
2 changes: 1 addition & 1 deletion libcxx/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ if(WIN32)
support/win32/support.cpp
)

if (NOT LIBCXX_HAS_PTHREAD_API)
if (NOT (LIBCXX_HAS_PTHREAD_API OR LIBCXX_HAS_MCF_THREAD_API))
list(APPEND LIBCXX_SOURCES
support/win32/thread_win32.cpp
)
Expand Down
28 changes: 28 additions & 0 deletions libcxxabi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ option(LIBCXXABI_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF)
option(LIBCXXABI_ENABLE_THREADS "Build with threads enabled" ON)
option(LIBCXXABI_HAS_PTHREAD_API "Ignore auto-detection and force use of pthread API" OFF)
option(LIBCXXABI_HAS_WIN32_THREAD_API "Ignore auto-detection and force use of win32 thread API" OFF)
option(LIBCXXABI_HAS_MCF_THREAD_API "Ignore auto-detection and force use of mcfgthread API" OFF)
option(LIBCXXABI_HAS_EXTERNAL_THREAD_API
"Build libc++abi with an externalized threading API.
This option may only be set to ON when LIBCXXABI_ENABLE_THREADS=ON." OFF)
Expand Down Expand Up @@ -318,6 +319,11 @@ if (NOT LIBCXXABI_ENABLE_THREADS)
" be set to ON when LIBCXXABI_ENABLE_THREADS"
" is also set to ON.")
endif()
if (LIBCXXABI_HAS_MCF_THREAD_API)
message(FATAL_ERROR "LIBCXXABI_HAS_MCF_THREAD_API can only"
" be set to ON when LIBCXXABI_ENABLE_THREADS"
" is also set to ON.")
endif()
add_definitions(-D_LIBCXXABI_HAS_NO_THREADS)
endif()

Expand All @@ -332,6 +338,11 @@ if (LIBCXXABI_HAS_EXTERNAL_THREAD_API)
" and LIBCXXABI_HAS_WIN32_THREAD_API cannot be both"
" set to ON at the same time.")
endif()
if (LIBCXXABI_HAS_MCF_THREAD_API)
message(FATAL_ERROR "The options LIBCXXABI_HAS_EXTERNAL_THREAD_API"
" and LIBCXXABI_HAS_MCF_THREAD_API cannot be both"
" set to ON at the same time.")
endif()
endif()

if (LIBCXXABI_HAS_PTHREAD_API)
Expand All @@ -340,6 +351,19 @@ if (LIBCXXABI_HAS_PTHREAD_API)
"and LIBCXXABI_HAS_WIN32_THREAD_API cannot be both"
"set to ON at the same time.")
endif()
if (LIBCXXABI_HAS_MCF_THREAD_API)
message(FATAL_ERROR "The options LIBCXXABI_HAS_PTHREAD_API"
"and LIBCXXABI_HAS_MCF_THREAD_API cannot be both"
"set to ON at the same time.")
endif()
endif()

if (LIBCXXABI_HAS_WIN32_THREAD_API)
if (LIBCXXABI_HAS_MCF_THREAD_API)
message(FATAL_ERROR "The options LIBCXXABI_HAS_WIN32_THREAD_API"
"and LIBCXXABI_HAS_MCF_THREAD_API cannot be both"
"set to ON at the same time.")
endif()
endif()

if (LLVM_ENABLE_MODULES)
Expand Down Expand Up @@ -375,6 +399,10 @@ if (LIBCXXABI_HAS_EXTERNAL_THREAD_API)
add_definitions(-D_LIBCPP_HAS_THREAD_API_EXTERNAL)
endif()

if (LIBCXXABI_HAS_MCF_THREAD_API)
add_definitions(-D_LIBCPP_HAS_THREAD_API_MCF)
endif()

if (MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()
Expand Down
4 changes: 4 additions & 0 deletions libcxxabi/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ if (ANDROID AND ANDROID_PLATFORM_LEVEL LESS 21)
list(APPEND LIBCXXABI_LIBRARIES android_support)
endif()

if (LIBCXXABI_HAS_MCF_THREAD_API)
list(APPEND LIBCXXABI_LIBRARIES mcfgthread ntdll)
endif()

# Setup flags.
if (CXX_SUPPORTS_NOSTDLIBXX_FLAG)
add_link_flags_if_supported(-nostdlib++)
Expand Down
47 changes: 46 additions & 1 deletion libcxxabi/src/cxa_guard_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
# if defined(__ELF__) && defined(_LIBCXXABI_LINK_PTHREAD_LIB)
# pragma comment(lib, "pthread")
# endif
# if _LIBCPP_HAS_THREAD_API_MCF
# include <mcfgthread/cxa.h>
# endif
#endif

#if defined(__clang__)
Expand Down Expand Up @@ -608,6 +611,38 @@ struct GuardObject {
}
};

//===----------------------------------------------------------------------===//
// GuardObject for MCF
//===----------------------------------------------------------------------===//

/// Forwards everything to libmcfgthread
struct GuardObject_MCF;
#if _LIBCPP_HAS_THREAD_API_MCF
struct GuardObject_MCF {
GuardObject_MCF() = delete;
GuardObject_MCF(GuardObject_MCF const&) = delete;
GuardObject_MCF& operator=(GuardObject_MCF const&) = delete;

private:
int64_t* guard_ptr;

public:
explicit GuardObject_MCF(uint64_t* raw_guard_object)
: guard_ptr(reinterpret_cast<int64_t*>(raw_guard_object)) { }

/// Implements __cxa_guard_acquire.
AcquireResult cxa_guard_acquire() {
return static_cast<AcquireResult>(__MCF_cxa_guard_acquire(guard_ptr));
}

/// Implements __cxa_guard_release.
void cxa_guard_release() { __MCF_cxa_guard_release(guard_ptr); }

/// Implements __cxa_guard_abort.
void cxa_guard_abort() { __MCF_cxa_guard_abort(guard_ptr); }
};
#endif

//===----------------------------------------------------------------------===//
// Convenience Classes
//===----------------------------------------------------------------------===//
Expand All @@ -628,6 +663,9 @@ template <void (*Wait)(int*, int) = PlatformFutexWait, void (*Wake)(int*) = Plat
uint32_t (*GetThreadIDArg)() = PlatformThreadID>
using FutexGuard = GuardObject<InitByteFutex<Wait, Wake, GetThreadIDArg>>;

/// MCFGuard - Forwards everything to libmcfgthread
using MCFGuard = GuardObject_MCF;

//===----------------------------------------------------------------------===//
//
//===----------------------------------------------------------------------===//
Expand All @@ -639,7 +677,7 @@ struct GlobalStatic {
template <class T>
_LIBCPP_CONSTINIT T GlobalStatic<T>::instance = {};

enum class Implementation { NoThreads, GlobalMutex, Futex };
enum class Implementation { NoThreads, GlobalMutex, Futex, MCF };

template <Implementation Impl>
struct SelectImplementation;
Expand All @@ -660,13 +698,20 @@ struct SelectImplementation<Implementation::Futex> {
using type = FutexGuard<PlatformFutexWait, PlatformFutexWake, PlatformThreadID>;
};

template <>
struct SelectImplementation<Implementation::MCF> {
using type = MCFGuard;
};

// TODO(EricWF): We should prefer the futex implementation when available. But
// it should be done in a separate step from adding the implementation.
constexpr Implementation CurrentImplementation =
#if defined(_LIBCXXABI_HAS_NO_THREADS)
Implementation::NoThreads;
#elif defined(_LIBCXXABI_USE_FUTEX)
Implementation::Futex;
#elif _LIBCPP_HAS_THREAD_API_MCF
Implementation::MCF;
#else
Implementation::GlobalMutex;
#endif
Expand Down
17 changes: 11 additions & 6 deletions libcxxabi/src/cxa_thread_atexit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@
#include "cxxabi.h"
#include <__thread/support.h>
#ifndef _LIBCXXABI_HAS_NO_THREADS
#if defined(__ELF__) && defined(_LIBCXXABI_LINK_PTHREAD_LIB)
#pragma comment(lib, "pthread")
#endif
# if defined(__ELF__) && defined(_LIBCXXABI_LINK_PTHREAD_LIB)
# pragma comment(lib, "pthread")
# endif
# if _LIBCPP_HAS_THREAD_API_MCF
# include <mcfgthread/cxa.h>
# endif
#endif

#include <stdlib.h>
Expand All @@ -22,14 +25,14 @@ namespace __cxxabiv1 {
using Dtor = void(*)(void*);

extern "C"
#ifndef HAVE___CXA_THREAD_ATEXIT_IMPL
#if !defined(HAVE___CXA_THREAD_ATEXIT_IMPL)
// A weak symbol is used to detect this function's presence in the C library
// at runtime, even if libc++ is built against an older libc
_LIBCXXABI_WEAK
#endif
int __cxa_thread_atexit_impl(Dtor, void*, void*);

#ifndef HAVE___CXA_THREAD_ATEXIT_IMPL
#if !(_LIBCPP_HAS_THREAD_API_MCF || defined(HAVE___CXA_THREAD_ATEXIT_IMPL))

namespace {
// This implementation is used if the C library does not provide
Expand Down Expand Up @@ -109,7 +112,9 @@ namespace {
extern "C" {

_LIBCXXABI_FUNC_VIS int __cxa_thread_atexit(Dtor dtor, void* obj, void* dso_symbol) throw() {
#ifdef HAVE___CXA_THREAD_ATEXIT_IMPL
#if _LIBCPP_HAS_THREAD_API_MCF
return __MCF_cxa_thread_atexit(dtor, obj, dso_symbol);
#elif defined(HAVE___CXA_THREAD_ATEXIT_IMPL)
return __cxa_thread_atexit_impl(dtor, obj, dso_symbol);
#else
if (__cxa_thread_atexit_impl) {
Expand Down
1 change: 1 addition & 0 deletions llvm/utils/gn/secondary/libcxx/include/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ if (current_toolchain == default_toolchain) {
"_LIBCPP_HAS_THREAD_API_PTHREAD=",
"_LIBCPP_HAS_THREAD_API_EXTERNAL=",
"_LIBCPP_HAS_THREAD_API_WIN32=",
"_LIBCPP_HAS_THREAD_API_MCF=",
"_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS=",
"_LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS=",
"_LIBCPP_NO_VCRUNTIME=",
Expand Down
Loading