mirror of
https://forge.sourceware.org/marek/gcc.git
synced 2026-02-22 03:47:02 -05:00
libstdc++: On Windows, retrieve thread-local variables via functions
For Windows, GCC can be configured with `--enable-tls` to enable native TLS. The native TLS implementation has a limitation that it is incapable of exporting thread-local variables from DLLs. Therefore, they are retrieved via getter functions instead. libstdc++-v3/ChangeLog: * config/os/mingw32-w64/os_defines.h (_GLIBCXX_NO_EXTERN_THREAD_LOCAL): New macro. * include/std/mutex [_GLIBCXX_NO_EXTERN_THREAD_LOCAL] (__get_once_callable, __get_once_call): Declare new functions. * src/c++11/mutex.cc [_GLIBCXX_NO_EXTERN_THREAD_LOCAL] (__get_once_callable, __get_once_call): Define. Signed-off-by: LIU Hao <lh_mouse@126.com> Co-authored-by: Jonathan Wakely <jwakely@redhat.com>
This commit is contained in:
@@ -96,4 +96,8 @@
|
||||
// See libstdc++/94268
|
||||
#define _GLIBCXX_BUFSIZ 4096
|
||||
|
||||
// Use functions to access thread-local variables from a different module.
|
||||
// Windows does not support exporting thread-local data.
|
||||
#define _GLIBCXX_NO_EXTERN_THREAD_LOCAL 1
|
||||
|
||||
#endif
|
||||
|
||||
@@ -817,9 +817,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
# ifdef _GLIBCXX_HAVE_TLS
|
||||
// If TLS is available use thread-local state for the type-erased callable
|
||||
// that is being run by std::call_once in the current thread.
|
||||
# ifdef _GLIBCXX_NO_EXTERN_THREAD_LOCAL
|
||||
|
||||
void*&
|
||||
__get_once_callable() noexcept;
|
||||
|
||||
std::add_lvalue_reference<void (*)()>::type
|
||||
__get_once_call() noexcept;
|
||||
|
||||
// These macros mean that all the code below uses the same syntax:
|
||||
#define __once_callable __get_once_callable()
|
||||
#define __once_call __get_once_call()
|
||||
|
||||
# else // ! _GLIBCXX_NO_EXTERN_THREAD_LOCAL
|
||||
|
||||
extern __thread void* __once_callable;
|
||||
extern __thread void (*__once_call)();
|
||||
|
||||
# endif // ! _GLIBCXX_NO_EXTERN_THREAD_LOCAL
|
||||
|
||||
// RAII type to set up state for pthread_once call.
|
||||
struct once_flag::_Prepare_execution
|
||||
{
|
||||
@@ -844,6 +860,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
_Prepare_execution& operator=(const _Prepare_execution&) = delete;
|
||||
};
|
||||
|
||||
#undef __once_callable
|
||||
#undef __once_call
|
||||
|
||||
# else
|
||||
// Without TLS use a global std::mutex and store the callable in a
|
||||
// global std::function.
|
||||
|
||||
@@ -34,6 +34,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__thread void* __once_callable;
|
||||
__thread void (*__once_call)();
|
||||
|
||||
# ifdef _GLIBCXX_NO_EXTERN_THREAD_LOCAL
|
||||
|
||||
// When thread-local variables can't be exported, these functions are called
|
||||
// to retrieve these variables.
|
||||
void*&
|
||||
__get_once_callable() noexcept
|
||||
{ return __once_callable; }
|
||||
|
||||
__typeof__(void (*)())&
|
||||
__get_once_call() noexcept
|
||||
{ return __once_call; }
|
||||
|
||||
# endif // _GLIBCXX_NO_EXTERN_THREAD_LOCAL
|
||||
|
||||
extern "C" void __once_proxy()
|
||||
{
|
||||
// The caller stored a function pointer in __once_call. If it requires
|
||||
|
||||
Reference in New Issue
Block a user