Merge branch 'always-use-thread-local'

Always use thread_local as we can rely on compiler TLS support working
under Windows 7 and later.

There are some known problems in MinGW thread local variable support,
but they only affect (obsolete) 32-bit builds and will hopefully be
fixed in this compiler soon.

See #22917.
This commit is contained in:
Vadim Zeitlin 2022-11-10 16:32:42 +01:00
commit b4b23ac423
29 changed files with 55 additions and 814 deletions

View file

@ -791,7 +791,6 @@ ALL_PORTS_BASE_HEADERS = \
wx/unix/evtloopsrc.h \
wx/unix/pipe.h \
wx/unix/stackwalk.h \
wx/unix/tls.h \
wx/unix/fswatcher_kqueue.h \
wx/unix/mimetype.h \
wx/unix/fswatcher_inotify.h \
@ -2536,7 +2535,6 @@ COND_TOOLKIT__BASE_OSX_HDR = \
wx/unix/evtloopsrc.h \
wx/unix/pipe.h \
wx/unix/stackwalk.h \
wx/unix/tls.h \
wx/unix/fswatcher_kqueue.h \
wx/unix/mimetype.h \
wx/osx/core/cfdataref.h \
@ -2564,7 +2562,6 @@ COND_TOOLKIT_COCOA_BASE_OSX_HDR = \
wx/unix/evtloopsrc.h \
wx/unix/pipe.h \
wx/unix/stackwalk.h \
wx/unix/tls.h \
wx/unix/fswatcher_kqueue.h \
wx/unix/mimetype.h \
wx/osx/core/cfdataref.h \
@ -2592,7 +2589,6 @@ COND_TOOLKIT_GTK_BASE_OSX_HDR = \
wx/unix/evtloopsrc.h \
wx/unix/pipe.h \
wx/unix/stackwalk.h \
wx/unix/tls.h \
wx/unix/fswatcher_kqueue.h \
wx/unix/mimetype.h \
wx/osx/core/cfdataref.h \
@ -2635,7 +2631,6 @@ COND_TOOLKIT_OSX_COCOA_BASE_OSX_HDR = \
wx/unix/evtloopsrc.h \
wx/unix/pipe.h \
wx/unix/stackwalk.h \
wx/unix/tls.h \
wx/unix/fswatcher_kqueue.h \
wx/osx/fswatcher_fsevents.h
@COND_TOOLKIT_OSX_COCOA@BASE_OSX_HDR = $(COND_TOOLKIT_OSX_COCOA_BASE_OSX_HDR)
@ -2648,7 +2643,6 @@ COND_TOOLKIT_X11_BASE_OSX_HDR = \
wx/unix/evtloopsrc.h \
wx/unix/pipe.h \
wx/unix/stackwalk.h \
wx/unix/tls.h \
wx/unix/fswatcher_kqueue.h \
wx/unix/mimetype.h \
wx/osx/core/cfdataref.h \
@ -2677,7 +2671,6 @@ COND_PLATFORM_UNIX_1_BASE_PLATFORM_HDR = \
wx/unix/evtloopsrc.h \
wx/unix/pipe.h \
wx/unix/stackwalk.h \
wx/unix/tls.h \
wx/unix/fswatcher_kqueue.h \
wx/unix/mimetype.h \
wx/unix/fswatcher_inotify.h \

View file

@ -85,7 +85,6 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
wx/unix/evtloopsrc.h
wx/unix/pipe.h
wx/unix/stackwalk.h
wx/unix/tls.h
wx/unix/fswatcher_kqueue.h
</set>

View file

@ -28,7 +28,6 @@ set(BASE_UNIX_AND_DARWIN_HDR
wx/unix/evtloopsrc.h
wx/unix/pipe.h
wx/unix/stackwalk.h
wx/unix/tls.h
wx/unix/fswatcher_kqueue.h
)

View file

@ -85,7 +85,6 @@ if(NOT WIN32)
wx_dependent_option(wxUSE_UTF8_LOCALE_ONLY "only support UTF-8 locales in UTF-8 build (Unix only)" ON "wxUSE_UNICODE_UTF8" OFF)
endif()
wx_option(wxUSE_COMPILER_TLS "enable use of compiler TLS support")
if(NOT WIN32)
wx_option(wxUSE_VISIBILITY "use of ELF symbols visibility")
endif()

View file

@ -441,19 +441,10 @@ if(CMAKE_USE_PTHREADS_INIT)
message(WARNING "wxMutex won't be recursive on this platform")
endif()
endif()
if(wxUSE_COMPILER_TLS)
# test for compiler thread-specific variables support
wx_check_c_source_compiles("
static __thread int n = 0;
static __thread int *p = 0;"
HAVE___THREAD_KEYWORD
pthread.h
)
wx_check_cxx_source_compiles(
"void foo(abi::__forced_unwind&);"
HAVE_ABI_FORCEDUNWIND
cxxabi.h)
endif()
wx_check_cxx_source_compiles(
"void foo(abi::__forced_unwind&);"
HAVE_ABI_FORCEDUNWIND
cxxabi.h)
cmake_pop_check_state()
endif() # CMAKE_USE_PTHREADS_INIT

View file

@ -168,8 +168,6 @@
#cmakedefine01 wxUSE_PRINTF_POS_PARAMS
#cmakedefine01 wxUSE_COMPILER_TLS
#cmakedefine01 wxUSE_STL

View file

@ -48,7 +48,6 @@ BASE_UNIX_AND_DARWIN_HDR =
wx/unix/evtloopsrc.h
wx/unix/pipe.h
wx/unix/stackwalk.h
wx/unix/tls.h
wx/unix/fswatcher_kqueue.h
# Files used on all Unix systems, including Darwin with any port but wxMac

View file

@ -390,10 +390,6 @@ def main(scriptName, args):
flags["wxUSE_AFM_FOR_POSTSCRIPT"] = "0"
flags["wxUSE_DATEPICKCTRL_GENERIC"] = "1"
# Remove this when Windows XP finally dies, or when there is a
# solution for ticket #13116...
flags["wxUSE_COMPILER_TLS"] = "0"
if VERSION < (2,9):
flags["wxUSE_DIB_FOR_BITMAP"] = "1"

204
configure vendored
View file

@ -947,7 +947,6 @@ GSPELL_LIBS
GSPELL_CFLAGS
LIBSECRET_LIBS
LIBSECRET_CFLAGS
GXX_VERSION
LIBICONV
CXXFLAGS_VISIBILITY
CFLAGS_VISIBILITY
@ -1144,7 +1143,6 @@ enable_compat30
enable_compat32
enable_rpath
enable_visibility
enable_tls
enable_repro_build
enable_pch
enable_intl
@ -2113,7 +2111,6 @@ Optional Features:
--disable-compat32 disable wxWidgets 3.2 compatibility
--disable-rpath disable use of rpath for uninstalled builds
--disable-visibility disable use of ELF symbols visibility even if supported
--disable-tls disable use of compiler TLS support
--enable-repro-build enable reproducible build mode
--enable-pch use precompiled headers if possible (off by default)
--enable-intl use internationalization system
@ -4065,7 +4062,6 @@ DEFAULT_wxUSE_UNICODE_UTF8=no
DEFAULT_wxUSE_UNICODE_UTF8_LOCALE=no
DEFAULT_wxUSE_ARTPROVIDER_TANGO=auto
DEFAULT_wxUSE_COMPILER_TLS=auto
DEFAULT_wxUSE_HOTKEY=auto
DEFAULT_wxUSE_MEDIACTRL=auto
DEFAULT_wxUSE_METAFILE=auto
@ -6277,35 +6273,6 @@ fi
eval "$wx_cv_use_visibility"
enablestring=disable
defaultval=
if test -z "$defaultval"; then
if test x"$enablestring" = xdisable; then
defaultval=yes
else
defaultval=no
fi
fi
# Check whether --enable-tls was given.
if test "${enable_tls+set}" = set; then :
enableval=$enable_tls;
if test "$enableval" = yes; then
wx_cv_use_tls='wxUSE_COMPILER_TLS=yes'
else
wx_cv_use_tls='wxUSE_COMPILER_TLS=no'
fi
else
wx_cv_use_tls='wxUSE_COMPILER_TLS=${'DEFAULT_wxUSE_COMPILER_TLS":-$defaultval}"
fi
eval "$wx_cv_use_tls"
enablestring=
defaultval=
@ -35211,178 +35178,27 @@ $as_echo "$as_me: WARNING: wxMutex won't be recursive on this platform" >&2;}
fi
fi
if test "$wxUSE_COMPILER_TLS" = "yes"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __thread keyword" >&5
$as_echo_n "checking for __thread keyword... " >&6; }
if ${wx_cv_cc___thread+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <pthread.h>
int
main ()
{
static __thread int n = 0;
static __thread int *p = 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
wx_cv_cc___thread=yes
else
wx_cv_cc___thread=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $wx_cv_cc___thread" >&5
$as_echo "$wx_cv_cc___thread" >&6; }
if test "$wx_cv_cc___thread" = "yes"; then
GXX_VERSION=""
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if gcc accepts -dumpversion option" >&5
$as_echo_n "checking if gcc accepts -dumpversion option... " >&6; }
if test "x$GCC" = "xyes" ; then :
if test -z "" ; then :
ax_gcc_option_test="int main()
{
return 0;
}"
else
ax_gcc_option_test=""
fi
# Dump the test program to file
cat <<EOF > conftest.c
$ax_gcc_option_test
EOF
# Dump back the file to the log, useful for debugging purposes
{ ac_try='cat conftest.c 1>&5'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; }
if { ac_try='$CC -dumpversion -c conftest.c 1>&5'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; } ; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
ax_gcc_version_option=yes
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
ax_gcc_version_option=no
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no gcc available" >&5
$as_echo "no gcc available" >&6; }
fi
if test "x$GXX" = "xyes"; then :
if test "x$ax_gxx_version_option" != "no"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking gxx version" >&5
$as_echo_n "checking gxx version... " >&6; }
if ${ax_cv_gxx_version+:} false; then :
$as_echo_n "(cached) " >&6
else
ax_cv_gxx_version="`$CXX -dumpversion`"
if test "x$ax_cv_gxx_version" = "x"; then :
ax_cv_gxx_version=""
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gxx_version" >&5
$as_echo "$ax_cv_gxx_version" >&6; }
GXX_VERSION=$ax_cv_gxx_version
fi
fi
if test -n "$ax_cv_gxx_version"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __thread support in g++ is usable" >&5
$as_echo_n "checking whether __thread support in g++ is usable... " >&6; }
case "$ax_cv_gxx_version" in
1.* | 2.* | 3.* )
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no, it's broken" >&5
$as_echo "no, it's broken" >&6; }
wx_cv_cc___thread=no
;;
*)
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, it works" >&5
$as_echo "yes, it works" >&6; }
;;
esac
fi
fi
if test "$wx_cv_cc___thread" = "yes"; then
$as_echo "#define HAVE___THREAD_KEYWORD 1" >>confdefs.h
fi
fi
if test "$ac_cv_header_cxxabi_h" = "yes"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for abi::__forced_unwind() in <cxxabi.h>" >&5
if test "$ac_cv_header_cxxabi_h" = "yes"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for abi::__forced_unwind() in <cxxabi.h>" >&5
$as_echo_n "checking for abi::__forced_unwind() in <cxxabi.h>... " >&6; }
if ${wx_cv_type_abi_forced_unwind+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_ext=cpp
ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <cxxabi.h>
int
main ()
{
void foo(abi::__forced_unwind&);
void foo(abi::__forced_unwind&);
;
return 0;
@ -35395,7 +35211,7 @@ else
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
ac_ext=c
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
@ -35406,16 +35222,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $wx_cv_type_abi_forced_unwind" >&5
$as_echo "$wx_cv_type_abi_forced_unwind" >&6; }
else
wx_cv_type_abi_forced_unwind=no
fi
if test "$wx_cv_type_abi_forced_unwind" = "yes"; then
$as_echo "#define HAVE_ABI_FORCEDUNWIND 1" >>confdefs.h
fi
fi
fi
else
if test "$wxUSE_THREADS" = "yes" ; then
case "${host}" in
@ -35844,9 +35657,6 @@ done
fi
$as_echo "#define wxUSE_COMPILER_TLS 1" >>confdefs.h
if test "$wxUSE_THREADS" = "yes"; then
$as_echo "#define wxUSE_THREADS 1" >>confdefs.h

View file

@ -347,7 +347,6 @@ DEFAULT_wxUSE_UNICODE_UTF8_LOCALE=no
dnl automatic features
DEFAULT_wxUSE_ARTPROVIDER_TANGO=auto
DEFAULT_wxUSE_COMPILER_TLS=auto
DEFAULT_wxUSE_HOTKEY=auto
DEFAULT_wxUSE_MEDIACTRL=auto
DEFAULT_wxUSE_METAFILE=auto
@ -700,7 +699,6 @@ WX_ARG_DISABLE(compat32, [ --disable-compat32 disable wxWidgets 3.2 co
WX_ARG_DISABLE(rpath, [ --disable-rpath disable use of rpath for uninstalled builds], wxUSE_RPATH)
WX_ARG_DISABLE(visibility, [ --disable-visibility disable use of ELF symbols visibility even if supported], wxUSE_VISIBILITY)
WX_ARG_DISABLE(tls, [ --disable-tls disable use of compiler TLS support], wxUSE_COMPILER_TLS)
WX_ARG_ENABLE(repro_build, [ --enable-repro-build enable reproducible build mode], wxUSE_REPRODUCIBLE_BUILD)
WX_ARG_ENABLE(pch, [ --enable-pch use precompiled headers if possible (off by default)], wxUSE_PCH)
@ -4622,75 +4620,27 @@ if test "$TOOLKIT" != "MSW"; then
fi
fi
if test "$wxUSE_COMPILER_TLS" = "yes"; then
dnl test for compiler thread-specific variables support
AC_CACHE_CHECK([for __thread keyword],
wx_cv_cc___thread,
[
AC_TRY_COMPILE([#include <pthread.h>],
[
static __thread int n = 0;
static __thread int *p = 0;
],
wx_cv_cc___thread=yes,
wx_cv_cc___thread=no
)
]
)
if test "$wx_cv_cc___thread" = "yes"; then
AX_GXX_VERSION
if test -n "$ax_cv_gxx_version"; then
dnl g++ supports __thread since at least version 3.3 but its support
dnl seems to be broken until 4.1, see
dnl http://thread.gmane.org/gmane.comp.lib.wxwidgets.devel/108388
dnl
dnl NB: we still need to test __thread support with
dnl AC_TRY_COMPILE above even for g++ 4 as it doesn't
dnl support it for all architectures (e.g. it doesn't
dnl work under OS X)
AC_MSG_CHECKING([whether __thread support in g++ is usable])
case "$ax_cv_gxx_version" in
1.* | 2.* | 3.* )
AC_MSG_RESULT([no, it's broken])
wx_cv_cc___thread=no
;;
*)
AC_MSG_RESULT([yes, it works])
;;
esac
fi
fi
if test "$wx_cv_cc___thread" = "yes"; then
AC_DEFINE(HAVE___THREAD_KEYWORD)
fi
fi
if test "$ac_cv_header_cxxabi_h" = "yes"; then
AC_CACHE_CHECK([for abi::__forced_unwind() in <cxxabi.h>],
wx_cv_type_abi_forced_unwind,
[
AC_LANG_PUSH(C++)
AC_TRY_COMPILE([#include <cxxabi.h>],
[
void foo(abi::__forced_unwind&);
],
wx_cv_type_abi_forced_unwind=yes,
wx_cv_type_abi_forced_unwind=no
)
AC_LANG_POP()
]
)
else
wx_cv_type_abi_forced_unwind=no
fi
if test "$ac_cv_header_cxxabi_h" = "yes"; then
AC_CACHE_CHECK([for abi::__forced_unwind() in <cxxabi.h>],
wx_cv_type_abi_forced_unwind,
[
AC_LANG_PUSH(C++)
AC_TRY_COMPILE([#include <cxxabi.h>],
[
void foo(abi::__forced_unwind&);
],
wx_cv_type_abi_forced_unwind=yes,
wx_cv_type_abi_forced_unwind=no
)
AC_LANG_POP()
]
)
if test "$wx_cv_type_abi_forced_unwind" = "yes"; then
AC_DEFINE(HAVE_ABI_FORCEDUNWIND)
fi
fi
fi
dnl from if !MSW
else
if test "$wxUSE_THREADS" = "yes" ; then
@ -4779,10 +4729,6 @@ dnl AC_CHECK_FUNC(getaddrinfo, AC_DEFINE(HAVE_GETADDRINFO), [
dnl ]
dnl )
dnl This is currently always defined under Unix, there is no reason to ever
dnl disable compiler TLS support there.
AC_DEFINE(wxUSE_COMPILER_TLS)
if test "$wxUSE_THREADS" = "yes"; then
AC_DEFINE(wxUSE_THREADS)

View file

@ -84,7 +84,6 @@ library:
@itemdef{wxUSE_COLOURPICKERCTRL, Use wxColourPickerCtrl class.}
@itemdef{wxUSE_COMBOBOX, Use wxComboBox class.}
@itemdef{wxUSE_COMBOCTRL, Use wxComboCtrl class.}
@itemdef{wxUSE_COMPILER_TLS, Can be set to 0 to prevent using compile thread-specific variables support.}
@itemdef{wxUSE_CONFIG, Use wxConfig and related classes.}
@itemdef{wxUSE_CONFIG_NATIVE, When enabled use native OS configuration instead of the wxFileConfig class.}
@itemdef{wxUSE_CONSOLE_EVENTLOOP, Enable event loop in console programs.}

View file

@ -274,25 +274,6 @@
// Recommended setting: 1 if you want to support multiple languages
#define wxUSE_PRINTF_POS_PARAMS 1
// Enable the use of compiler-specific thread local storage keyword, if any.
// This is used for wxTLS_XXX() macros implementation and normally should use
// the compiler-provided support as it's simpler and more efficient, but is
// disabled under Windows in wx/msw/chkconf.h as it can't be used if wxWidgets
// is used in a dynamically loaded Win32 DLL (i.e. using LoadLibrary()) under
// XP as this triggers a bug in compiler TLS support that results in crashes
// when any TLS variables are used.
//
// If you're absolutely sure that your build of wxWidgets is never going to be
// used in such situation, either because it's not going to be linked from any
// kind of plugin or because you only target Vista or later systems, you can
// set this to 2 to force the use of compiler TLS even under MSW.
//
// Default is 1 meaning that compiler TLS is used only if it's 100% safe.
//
// Recommended setting: 2 if you want to have maximal performance and don't
// care about the scenario described above.
#define wxUSE_COMPILER_TLS 1
// ----------------------------------------------------------------------------
// Interoperability with the standard library.
// ----------------------------------------------------------------------------

View file

@ -88,14 +88,6 @@
# endif
#endif /* wxUSE_ANY */
#ifndef wxUSE_COMPILER_TLS
# ifdef wxABORT_ON_CONFIG_ERROR
# error "wxUSE_COMPILER_TLS must be defined, please read comment near the top of this file."
# else
# define wxUSE_COMPILER_TLS 0
# endif
#endif /* !defined(wxUSE_COMPILER_TLS) */
#ifndef wxUSE_CONSOLE_EVENTLOOP
# ifdef wxABORT_ON_CONFIG_ERROR
# error "wxUSE_CONSOLE_EVENTLOOP must be defined, please read comment near the top of this file."

View file

@ -275,25 +275,6 @@
// Recommended setting: 1 if you want to support multiple languages
#define wxUSE_PRINTF_POS_PARAMS 1
// Enable the use of compiler-specific thread local storage keyword, if any.
// This is used for wxTLS_XXX() macros implementation and normally should use
// the compiler-provided support as it's simpler and more efficient, but is
// disabled under Windows in wx/msw/chkconf.h as it can't be used if wxWidgets
// is used in a dynamically loaded Win32 DLL (i.e. using LoadLibrary()) under
// XP as this triggers a bug in compiler TLS support that results in crashes
// when any TLS variables are used.
//
// If you're absolutely sure that your build of wxWidgets is never going to be
// used in such situation, either because it's not going to be linked from any
// kind of plugin or because you only target Vista or later systems, you can
// set this to 2 to force the use of compiler TLS even under MSW.
//
// Default is 1 meaning that compiler TLS is used only if it's 100% safe.
//
// Recommended setting: 2 if you want to have maximal performance and don't
// care about the scenario described above.
#define wxUSE_COMPILER_TLS 1
// ----------------------------------------------------------------------------
// Interoperability with the standard library.
// ----------------------------------------------------------------------------

View file

@ -275,25 +275,6 @@
// Recommended setting: 1 if you want to support multiple languages
#define wxUSE_PRINTF_POS_PARAMS 1
// Enable the use of compiler-specific thread local storage keyword, if any.
// This is used for wxTLS_XXX() macros implementation and normally should use
// the compiler-provided support as it's simpler and more efficient, but is
// disabled under Windows in wx/msw/chkconf.h as it can't be used if wxWidgets
// is used in a dynamically loaded Win32 DLL (i.e. using LoadLibrary()) under
// XP as this triggers a bug in compiler TLS support that results in crashes
// when any TLS variables are used.
//
// If you're absolutely sure that your build of wxWidgets is never going to be
// used in such situation, either because it's not going to be linked from any
// kind of plugin or because you only target Vista or later systems, you can
// set this to 2 to force the use of compiler TLS even under MSW.
//
// Default is 1 meaning that compiler TLS is used only if it's 100% safe.
//
// Recommended setting: 2 if you want to have maximal performance and don't
// care about the scenario described above.
#define wxUSE_COMPILER_TLS 1
// ----------------------------------------------------------------------------
// Interoperability with the standard library.
// ----------------------------------------------------------------------------

View file

@ -1,123 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/tls.h
// Purpose: Win32 implementation of wxTlsValue<>
// Author: Vadim Zeitlin
// Created: 2008-08-08
// Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_TLS_H_
#define _WX_MSW_TLS_H_
#include "wx/msw/wrapwin.h"
#include "wx/thread.h"
#include "wx/vector.h"
// ----------------------------------------------------------------------------
// wxTlsKey is a helper class encapsulating a TLS slot
// ----------------------------------------------------------------------------
class wxTlsKey
{
public:
// ctor allocates a new key
wxTlsKey(wxTlsDestructorFunction destructor)
{
m_destructor = destructor;
m_slot = ::TlsAlloc();
}
// return true if the key was successfully allocated
bool IsOk() const { return m_slot != TLS_OUT_OF_INDEXES; }
// get the key value, there is no error return
void *Get() const
{
// Exceptionally, TlsGetValue() calls SetLastError() even on success
// which means it overwrites the previous value. This is undesirable
// here, so explicitly preserve the last error here.
const DWORD dwLastError = ::GetLastError();
void* const value = ::TlsGetValue(m_slot);
if ( dwLastError )
::SetLastError(dwLastError);
return value;
}
// change the key value, return true if ok
bool Set(void *value)
{
void *old = Get();
if ( ::TlsSetValue(m_slot, value) == 0 )
return false;
if ( old )
m_destructor(old);
// update m_allValues list of all values - remove old, add new
wxCriticalSectionLocker lock(m_csAllValues);
if ( old )
{
for ( wxVector<void*>::iterator i = m_allValues.begin();
i != m_allValues.end();
++i )
{
if ( *i == old )
{
if ( value )
*i = value;
else
m_allValues.erase(i);
return true;
}
}
wxFAIL_MSG( "previous wxTlsKey value not recorded in m_allValues" );
}
if ( value )
m_allValues.push_back(value);
return true;
}
// free the key
~wxTlsKey()
{
if ( !IsOk() )
return;
// Win32 API doesn't have the equivalent of pthread's destructor, so we
// have to keep track of all allocated values and destroy them manually;
// ideally we'd do that at thread exit time, but since we could only
// do that with wxThread and not otherwise created threads, we do it
// here.
//
// TODO: We should still call destructors for wxTlsKey used in the
// thread from wxThread's thread shutdown code, *in addition*
// to doing it in ~wxTlsKey.
//
// NB: No need to lock m_csAllValues, by the time this code is called,
// no other thread can be using this key.
for ( wxVector<void*>::iterator i = m_allValues.begin();
i != m_allValues.end();
++i )
{
m_destructor(*i);
}
::TlsFree(m_slot);
}
private:
wxTlsDestructorFunction m_destructor;
DWORD m_slot;
wxVector<void*> m_allValues;
wxCriticalSection m_csAllValues;
wxDECLARE_NO_COPY_CLASS(wxTlsKey);
};
#endif // _WX_MSW_TLS_H_

View file

@ -281,25 +281,6 @@
// Recommended setting: 1 if you want to support multiple languages
#define wxUSE_PRINTF_POS_PARAMS 1
// Enable the use of compiler-specific thread local storage keyword, if any.
// This is used for wxTLS_XXX() macros implementation and normally should use
// the compiler-provided support as it's simpler and more efficient, but is
// disabled under Windows in wx/msw/chkconf.h as it can't be used if wxWidgets
// is used in a dynamically loaded Win32 DLL (i.e. using LoadLibrary()) under
// XP as this triggers a bug in compiler TLS support that results in crashes
// when any TLS variables are used.
//
// If you're absolutely sure that your build of wxWidgets is never going to be
// used in such situation, either because it's not going to be linked from any
// kind of plugin or because you only target Vista or later systems, you can
// set this to 2 to force the use of compiler TLS even under MSW.
//
// Default is 1 meaning that compiler TLS is used only if it's 100% safe.
//
// Recommended setting: 2 if you want to have maximal performance and don't
// care about the scenario described above.
#define wxUSE_COMPILER_TLS 1
// ----------------------------------------------------------------------------
// Interoperability with the standard library.
// ----------------------------------------------------------------------------

View file

@ -271,25 +271,6 @@
// Recommended setting: 1 if you want to support multiple languages
#define wxUSE_PRINTF_POS_PARAMS 1
// Enable the use of compiler-specific thread local storage keyword, if any.
// This is used for wxTLS_XXX() macros implementation and normally should use
// the compiler-provided support as it's simpler and more efficient, but is
// disabled under Windows in wx/msw/chkconf.h as it can't be used if wxWidgets
// is used in a dynamically loaded Win32 DLL (i.e. using LoadLibrary()) under
// XP as this triggers a bug in compiler TLS support that results in crashes
// when any TLS variables are used.
//
// If you're absolutely sure that your build of wxWidgets is never going to be
// used in such situation, either because it's not going to be linked from any
// kind of plugin or because you only target Vista or later systems, you can
// set this to 2 to force the use of compiler TLS even under MSW.
//
// Default is 1 meaning that compiler TLS is used only if it's 100% safe.
//
// Recommended setting: 2 if you want to have maximal performance and don't
// care about the scenario described above.
#define wxUSE_COMPILER_TLS 1
// ----------------------------------------------------------------------------
// Interoperability with the standard library.
// ----------------------------------------------------------------------------

View file

@ -48,14 +48,7 @@
// notice that this optimization is well worth using even in debug builds as it
// changes asymptotic complexity of algorithms using indices to iterate over
// wxString back to expected linear from quadratic
//
// also notice that wxTLS_TYPE() (__declspec(thread) in this case) is unsafe to
// use in DLL build under pre-Vista Windows so we disable this code for now, if
// anybody really needs to use UTF-8 build under Windows with this optimization
// it would have to be re-tested and probably corrected
// CS: under OSX release builds the string destructor/cache cleanup sometimes
// crashes, disable until we find the true reason or a better workaround
#if wxUSE_UNICODE_UTF8 && !defined(__WINDOWS__) && !defined(__WXOSX__)
#if wxUSE_UNICODE_UTF8
#define wxUSE_STRING_POS_CACHE 1
#else
#define wxUSE_STRING_POS_CACHE 0
@ -430,34 +423,8 @@ private:
unsigned lastUsed;
};
#ifndef wxHAS_COMPILER_TLS
// we must use an accessor function and not a static variable when the TLS
// variables support is implemented in the library (and not by the compiler)
// because the global s_cache variable could be not yet initialized when a
// ctor of another global object is executed and if that ctor uses any
// wxString methods, bad things happen
//
// however notice that this approach does not work when compiler TLS is used,
// at least not with g++ 4.1.2 under amd64 as it apparently compiles code
// using this accessor incorrectly when optimizations are enabled (-O2 is
// enough) -- luckily we don't need it then either as static __thread
// variables are initialized by 0 anyhow then and so we can use the variable
// directly
WXEXPORT static Cache& GetCache()
{
static wxTLS_TYPE(Cache) s_cache;
return wxTLS_VALUE(s_cache);
}
// this helper struct is used to ensure that GetCache() is called during
// static initialization time, i.e. before any threads creation, as otherwise
// the static s_cache construction inside GetCache() wouldn't be MT-safe
friend struct wxStrCacheInitializer;
#else // wxHAS_COMPILER_TLS
static wxTLS_TYPE(Cache) ms_cache;
static Cache& GetCache() { return wxTLS_VALUE(ms_cache); }
#endif // !wxHAS_COMPILER_TLS/wxHAS_COMPILER_TLS
static wxTHREAD_SPECIFIC_DECL Cache ms_cache;
static Cache& GetCache() { return ms_cache; }
static Cache::Element *GetCacheBegin() { return GetCache().cached; }
static Cache::Element *GetCacheEnd() { return GetCacheBegin() + Cache::SIZE; }
@ -508,12 +475,6 @@ private:
// simple loop instead of starting from the last used element (there are
// a lot of misses in this function...)
Cache::Element * const cacheBegin = GetCacheBegin();
#ifndef wxHAS_COMPILER_TLS
// during destruction tls calls may return nullptr, in this case return nullptr
// immediately without accessing anything else
if ( cacheBegin == nullptr )
return nullptr;
#endif
// gcc 7 warns about not being able to optimize this loop because of
// possible loop variable overflow, really not sure what to do about

View file

@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/tls.h
// Purpose: Implementation of thread local storage
// Purpose: Implementation of thread local storage (obsolete)
// Author: Vadim Zeitlin
// Created: 2008-08-08
// Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
@ -19,125 +19,24 @@
// when not using threads at all, there is no need for thread-specific
// values to be really thread-specific
#if !wxUSE_THREADS
#define wxHAS_COMPILER_TLS
#define wxTHREAD_SPECIFIC_DECL
// otherwise try to find the compiler-specific way to handle TLS unless
// explicitly disabled by setting wxUSE_COMPILER_TLS to 0 (it is 1 by default).
#elif wxUSE_COMPILER_TLS
// __thread keyword is not supported correctly by MinGW, at least in some
// configurations, see http://sourceforge.net/support/tracker.php?aid=2837047
// and when in doubt we prefer to not use it at all.
#if defined(HAVE___THREAD_KEYWORD) && !defined(__MINGW32__)
#define wxHAS_COMPILER_TLS
#define wxTHREAD_SPECIFIC_DECL __thread
// MSVC has its own version which might be supported by some other Windows
// compilers, to be tested
#elif defined(__VISUALC__)
#define wxHAS_COMPILER_TLS
#define wxTHREAD_SPECIFIC_DECL __declspec(thread)
#endif // compilers
#endif // wxUSE_COMPILER_TLS
#else
#define wxTHREAD_SPECIFIC_DECL thread_local
#endif
// ----------------------------------------------------------------------------
// define wxTLS_TYPE()
// ----------------------------------------------------------------------------
#ifdef wxHAS_COMPILER_TLS
#define wxTLS_TYPE(T) wxTHREAD_SPECIFIC_DECL T
#define wxTLS_TYPE_REF(T) T&
#define wxTLS_PTR(var) (&(var))
#define wxTLS_VALUE(var) (var)
#else // !wxHAS_COMPILER_TLS
// All these preprocessor symbols are obsolete and defined only for
// compatibility: C++11 compilers always support variables with thread storage,
// so you should just always use thread_local directly in the new code instead.
#define wxHAS_COMPILER_TLS
extern "C"
{
typedef void (*wxTlsDestructorFunction)(void*);
}
#if defined(__WINDOWS__)
#include "wx/msw/tls.h"
#elif defined(__UNIX__)
#include "wx/unix/tls.h"
#else
// TODO: we could emulate TLS for such platforms...
#error Neither compiler nor OS support thread-specific variables.
#endif
#include <stdlib.h> // for calloc()
// wxTlsValue<T> represents a thread-specific value of type T but, unlike
// with native compiler thread-specific variables, it behaves like a
// (never null) pointer to T and so needs to be dereferenced before use
//
// Note: T must be a POD!
//
// Note: On Unix, thread-specific T value is freed when the thread exits.
// On Windows, thread-specific values are freed later, when given
// wxTlsValue<T> is destroyed. The only exception to this is the
// value for the main thread, which is always freed when
// wxTlsValue<T> is destroyed.
template <typename T>
class wxTlsValue
{
public:
typedef T ValueType;
// ctor doesn't do anything, the object is created on first access
wxTlsValue() : m_key(free) {}
// dtor is only called in the main thread context and so is not enough
// to free memory allocated by us for the other threads, we use
// destructor function when using Pthreads for this (which is not
// called for the main thread as it doesn't call pthread_exit() but
// just to be safe we also reset the key anyhow)
~wxTlsValue()
{
if ( m_key.Get() )
m_key.Set(nullptr); // this deletes the value
}
// access the object creating it on demand
ValueType *Get()
{
void *value = m_key.Get();
if ( !value )
{
// ValueType must be POD to be used in wxHAS_COMPILER_TLS case
// anyhow (at least gcc doesn't accept non-POD values being
// declared with __thread) so initialize it as a POD too
value = calloc(1, sizeof(ValueType));
if ( !m_key.Set(value) )
{
free(value);
// this will probably result in a crash in the caller but
// it's arguably better to crash immediately instead of
// slowly dying from out-of-memory errors which would
// happen as the next access to this object would allocate
// another ValueType instance and so on forever
value = nullptr;
}
}
return static_cast<ValueType *>(value);
}
// pointer-like accessors
ValueType *operator->() { return Get(); }
ValueType& operator*() { return *Get(); }
private:
wxTlsKey m_key;
wxDECLARE_NO_COPY_TEMPLATE_CLASS(wxTlsValue, T);
};
#define wxTLS_TYPE(T) wxTlsValue<T>
#define wxTLS_TYPE_REF(T) wxTLS_TYPE(T)&
#define wxTLS_PTR(var) ((var).Get())
#define wxTLS_VALUE(var) (*(var))
#endif // wxHAS_COMPILER_TLS/!wxHAS_COMPILER_TLS
#define wxTLS_TYPE(T) wxTHREAD_SPECIFIC_DECL T
#define wxTLS_TYPE_REF(T) T&
#define wxTLS_PTR(var) (&(var))
#define wxTLS_VALUE(var) (var)
#endif // _WX_TLS_H_

View file

@ -274,25 +274,6 @@
// Recommended setting: 1 if you want to support multiple languages
#define wxUSE_PRINTF_POS_PARAMS 1
// Enable the use of compiler-specific thread local storage keyword, if any.
// This is used for wxTLS_XXX() macros implementation and normally should use
// the compiler-provided support as it's simpler and more efficient, but is
// disabled under Windows in wx/msw/chkconf.h as it can't be used if wxWidgets
// is used in a dynamically loaded Win32 DLL (i.e. using LoadLibrary()) under
// XP as this triggers a bug in compiler TLS support that results in crashes
// when any TLS variables are used.
//
// If you're absolutely sure that your build of wxWidgets is never going to be
// used in such situation, either because it's not going to be linked from any
// kind of plugin or because you only target Vista or later systems, you can
// set this to 2 to force the use of compiler TLS even under MSW.
//
// Default is 1 meaning that compiler TLS is used only if it's 100% safe.
//
// Recommended setting: 2 if you want to have maximal performance and don't
// care about the scenario described above.
#define wxUSE_COMPILER_TLS 1
// ----------------------------------------------------------------------------
// Interoperability with the standard library.
// ----------------------------------------------------------------------------

View file

@ -1,65 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/unix/tls.h
// Purpose: Pthreads implementation of wxTlsValue<>
// Author: Vadim Zeitlin
// Created: 2008-08-08
// Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_UNIX_TLS_H_
#define _WX_UNIX_TLS_H_
#include <pthread.h>
// ----------------------------------------------------------------------------
// wxTlsKey is a helper class encapsulating the TLS value index
// ----------------------------------------------------------------------------
class wxTlsKey
{
public:
// ctor allocates a new key and possibly registering a destructor function
// for it
wxTlsKey(wxTlsDestructorFunction destructor)
{
m_destructor = destructor;
if ( pthread_key_create(&m_key, destructor) != 0 )
m_key = 0;
}
// return true if the key was successfully allocated
bool IsOk() const { return m_key != 0; }
// get the key value, there is no error return
void *Get() const
{
return pthread_getspecific(m_key);
}
// change the key value, return true if ok
bool Set(void *value)
{
void *old = Get();
if ( old )
m_destructor(old);
return pthread_setspecific(m_key, value) == 0;
}
// free the key
~wxTlsKey()
{
if ( IsOk() )
pthread_key_delete(m_key);
}
private:
wxTlsDestructorFunction m_destructor;
pthread_key_t m_key;
wxDECLARE_NO_COPY_CLASS(wxTlsKey);
};
#endif // _WX_UNIX_TLS_H_

View file

@ -6,6 +6,8 @@
/////////////////////////////////////////////////////////////////////////////
/**
@deprecated Use C++11 `thread_local` keyword instead.
Macro to be used for thread-specific variables declarations.
This macro can be used to define thread-specific variables of the specified
@ -37,6 +39,8 @@
#define wxTLS_TYPE(type) compiler-dependent-implementation
/**
@deprecated Use variables defined using C++11 `thread_local` keyword normally.
Macro to access thread-specific variables.
This macro is used to hide the difference in implementation of
@ -55,6 +59,8 @@
#define wxTLS_VALUE(var)
/**
@deprecated Use variables defined using C++11 `thread_local` keyword normally.
Macro to return address of a thread-specific variables.
This macro is similar to wxTLS_VALUE() except that it always returns a

View file

@ -171,8 +171,6 @@
#define wxUSE_PRINTF_POS_PARAMS 0
#define wxUSE_COMPILER_TLS 0
#define wxUSE_STL 0
@ -779,10 +777,6 @@
* Define if you have pthread_cleanup_push/pop()
*/
#undef wxHAVE_PTHREAD_CLEANUP
/*
* Define if compiler has __thread keyword.
*/
#undef HAVE___THREAD_KEYWORD
/*
* Define if large (64 bit file offsets) files are supported.
*/

View file

@ -157,8 +157,6 @@ typedef pid_t GPid;
/* --- start common options --- */
#define wxUSE_COMPILER_TLS 1
#ifndef wxUSE_GUI
#define wxUSE_GUI 1
#endif
@ -857,11 +855,6 @@ typedef pid_t GPid;
*/
#define wxHAVE_PTHREAD_CLEANUP 1
/*
* Define if compiler has __thread keyword.
*/
#undef HAVE___THREAD_KEYWORD
/*
* Define if large (64 bit file offsets) files are supported.
*/

View file

@ -81,34 +81,7 @@ const size_t wxString::npos = (size_t) -1;
#if wxUSE_STRING_POS_CACHE
#ifdef wxHAS_COMPILER_TLS
wxTLS_TYPE(wxString::Cache) wxString::ms_cache;
#else // !wxHAS_COMPILER_TLS
struct wxStrCacheInitializer
{
wxStrCacheInitializer()
{
// calling this function triggers s_cache initialization in it, and
// from now on it becomes safe to call from multiple threads
wxString::GetCache();
}
};
/*
wxString::Cache& wxString::GetCache()
{
static wxTLS_TYPE(Cache) s_cache;
return wxTLS_VALUE(s_cache);
}
*/
static wxStrCacheInitializer gs_stringCacheInit;
#endif // wxHAS_COMPILER_TLS/!wxHAS_COMPILER_TLS
wxTHREAD_SPECIFIC_DECL wxString::Cache wxString::ms_cache;
// gdb seems to be unable to display thread-local variables correctly, at least
// not my 6.4.98 version under amd64, so provide this debugging helper to do it

View file

@ -45,14 +45,14 @@ inline wxAllThreadInfos& GetAllThreadInfos()
}
// Pointer to the current thread's instance
inline wxTLS_TYPE_REF(wxThreadSpecificInfo*) GetThisThreadInfo()
inline wxThreadSpecificInfo*& GetThisThreadInfo()
{
static wxTLS_TYPE(wxThreadSpecificInfo*) s_thisThreadInfo;
static wxTHREAD_SPECIFIC_DECL wxThreadSpecificInfo* s_thisThreadInfo;
return s_thisThreadInfo;
}
#define wxTHIS_THREAD_INFO wxTLS_VALUE(GetThisThreadInfo())
#define wxTHIS_THREAD_INFO GetThisThreadInfo()
} // anonymous namespace

View file

@ -175,8 +175,7 @@ BENCHMARK_FUNC(BoostTLS)
BENCHMARK_FUNC(wxTLS)
{
static wxTLS_TYPE(int) s_globalVar;
#define s_global wxTLS_VALUE(s_globalVar)
static wxTHREAD_SPECIFIC_DECL int s_global;
for ( int n = 0; n < NUM_ITER; n++ )
{

View file

@ -35,11 +35,8 @@ struct PerThreadData
int number;
};
wxTLS_TYPE(PerThreadData) gs_threadDataVar;
#define gs_threadData wxTLS_VALUE(gs_threadDataVar)
wxTLS_TYPE(int) gs_threadIntVar;
#define gs_threadInt wxTLS_VALUE(gs_threadIntVar)
wxTHREAD_SPECIFIC_DECL PerThreadData gs_threadData;
wxTHREAD_SPECIFIC_DECL int gs_threadInt;
// ----------------------------------------------------------------------------
// test thread