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

@ -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