diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2021-11-19 12:26:49 +0000 |
---|---|---|
committer | Jonathan Wakely <jwakely@redhat.com> | 2021-11-19 20:22:52 +0000 |
commit | 5faf1c8c7ab64340945972ee5acb9eb0a655567a (patch) | |
tree | ab1a05f24e1885afd867d1d41ce649fc0cc5a2e7 | |
parent | 1f8d01eb1476a997eb1fc686b60fccdf97747faa (diff) | |
download | gcc-5faf1c8c7ab64340945972ee5acb9eb0a655567a.tar.gz |
libstdc++: Use __is_single_threaded in locale initialization
This replaces a __gthread_active_p() check with __is_single_threaded()
so that std::locale initialization doesn't use __gthread_once if it
happens before the first thread is created.
This means that _S_initialize_once() might now be called twice instead
of only once, because if __is_single_threaded() changes to false then we
will do the __gthread_once call even if _S_initialize_once() was already
called. Add a check to _S_initialize_once() and return immediately if
it is the second call.
Also use __builtin_expect to _S_initialize, as the branch will be taken
at most once in the lifetime of the program.
libstdc++-v3/ChangeLog:
* src/c++98/locale_init.cc (_S_initialize_once): Check if
initialization has already been done.
(_S_initialize): Replace __gthread_active_p with
__is_single_threaded. Use __builtin_expect.
-rw-r--r-- | libstdc++-v3/src/c++98/locale_init.cc | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/libstdc++-v3/src/c++98/locale_init.cc b/libstdc++-v3/src/c++98/locale_init.cc index e96b1a336aa..ff563b80465 100644 --- a/libstdc++-v3/src/c++98/locale_init.cc +++ b/libstdc++-v3/src/c++98/locale_init.cc @@ -31,6 +31,7 @@ #include <cctype> #include <cwctype> // For towupper, etc. #include <locale> +#include <ext/atomicity.h> #include <ext/concurrence.h> #if _GLIBCXX_USE_DUAL_ABI @@ -321,6 +322,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void locale::_S_initialize_once() throw() { + // Need to check this because we could get called once from _S_initialize() + // when the program is single-threaded, and then again (via __gthread_once) + // when it's multi-threaded. + if (_S_classic) + return; + // 2 references. // One reference for _S_classic, one for _S_global _S_classic = new (&c_locale_impl) _Impl(2); @@ -332,10 +339,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION locale::_S_initialize() { #ifdef __GTHREADS - if (__gthread_active_p()) + if (!__gnu_cxx::__is_single_threaded()) __gthread_once(&_S_once, _S_initialize_once); #endif - if (!_S_classic) + if (__builtin_expect(!_S_classic, 0)) _S_initialize_once(); } |