access TLS cache variable directly and not via a helper function when using compiler with native TLS support to work around an apparent bug in g++
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55501 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -594,11 +594,19 @@ private:
|
|||||||
unsigned lastUsed;
|
unsigned lastUsed;
|
||||||
};
|
};
|
||||||
|
|
||||||
// notice that we must use an accessor function and not a static variable
|
#ifndef wxHAS_COMPILER_TLS
|
||||||
// because when the TLS variables support is implemented in the library (and
|
// we must use an accessor function and not a static variable when the TLS
|
||||||
// not by the compiler), the global s_cache variable could be not yet
|
// variables support is implemented in the library (and not by the compiler)
|
||||||
// initialized when a ctor of another global object is executed and if that
|
// because the global s_cache variable could be not yet initialized when a
|
||||||
// ctor uses any wxString methods, bad things happen
|
// 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 neither as static __thread
|
||||||
|
// variables are initialized by 0 anyhow then and so we can use the variable
|
||||||
|
// directly
|
||||||
static Cache& GetCache()
|
static Cache& GetCache()
|
||||||
{
|
{
|
||||||
static wxTLS_TYPE(Cache) s_cache;
|
static wxTLS_TYPE(Cache) s_cache;
|
||||||
@@ -606,14 +614,18 @@ private:
|
|||||||
return wxTLS_VALUE(s_cache);
|
return wxTLS_VALUE(s_cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Cache::Element *GetCacheBegin() { return GetCache().cached; }
|
|
||||||
static Cache::Element *GetCacheEnd() { return GetCacheBegin() + Cache::SIZE; }
|
|
||||||
static unsigned& LastUsedCacheElement() { return GetCache().lastUsed; }
|
|
||||||
|
|
||||||
// this helper struct is used to ensure that GetCache() is called during
|
// this helper struct is used to ensure that GetCache() is called during
|
||||||
// static initialization time, i.e. before any threads creation, as otherwise
|
// static initialization time, i.e. before any threads creation, as otherwise
|
||||||
// the static s_cache construction inside GetCache() wouldn't be MT-safe
|
// the static s_cache construction inside GetCache() wouldn't be MT-safe
|
||||||
friend struct wxStrCacheInitializer;
|
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 Cache::Element *GetCacheBegin() { return GetCache().cached; }
|
||||||
|
static Cache::Element *GetCacheEnd() { return GetCacheBegin() + Cache::SIZE; }
|
||||||
|
static unsigned& LastUsedCacheElement() { return GetCache().lastUsed; }
|
||||||
|
|
||||||
// this is used in debug builds only to provide a convenient function,
|
// this is used in debug builds only to provide a convenient function,
|
||||||
// callable from a debugger, to show the cache contents
|
// callable from a debugger, to show the cache contents
|
||||||
|
@@ -60,6 +60,12 @@ const size_t wxString::npos = (size_t) -1;
|
|||||||
|
|
||||||
#if wxUSE_STRING_POS_CACHE
|
#if wxUSE_STRING_POS_CACHE
|
||||||
|
|
||||||
|
#ifdef wxHAS_COMPILER_TLS
|
||||||
|
|
||||||
|
wxTLS_TYPE(wxString::Cache) wxString::ms_cache;
|
||||||
|
|
||||||
|
#else // !wxHAS_COMPILER_TLS
|
||||||
|
|
||||||
struct wxStrCacheInitializer
|
struct wxStrCacheInitializer
|
||||||
{
|
{
|
||||||
wxStrCacheInitializer()
|
wxStrCacheInitializer()
|
||||||
@@ -72,6 +78,8 @@ struct wxStrCacheInitializer
|
|||||||
|
|
||||||
static wxStrCacheInitializer gs_stringCacheInit;
|
static wxStrCacheInitializer gs_stringCacheInit;
|
||||||
|
|
||||||
|
#endif // wxHAS_COMPILER_TLS/!wxHAS_COMPILER_TLS
|
||||||
|
|
||||||
// gdb seems to be unable to display thread-local variables correctly, at least
|
// 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
|
// not my 6.4.98 version under amd64, so provide this debugging helper to do it
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
|
Reference in New Issue
Block a user