When a std::ostringstream object is created, it references a locale object which is synchronized by a global mutex.
This causes a significant performance problem for multi-threaded applications running on systems with many CPU's if they use string streams frequently.
System type? More generally, please provide all the informations detailed in:
It's the default contructor of std::locale.
David, are you aware of implementations not affected by this problem while providing thread-safe locale::locale() and locale::global, thus much smarter in the way ios_base deals with locale or you have a feeling it's just that a thread-safe global locale doesn't play well with multi-threading?
Hm. I wonder how the "global" locale is supposed to interact with multiple
threads anyway (in the face of C++ not knowing about threads). Would it be
a conforming implementation to put the global locale into thread-local storage
(thus, having a "global" locale for each thread)?
Btw, from a quick look the global mutex could be easily replaced with
atomic updates of the reference counts (it seems they already are
atomic) and atomic exchanges of the locale pointer.
Atomically fetching the current global locale and adding a reference to it
(huh, it looks like we leak locales that become global? at lest we do not
drop references from the global locale we replace in locale::global(const locale&)) is easy (pointer reads are atomic if the pointer is naturally
aligned) - a special case would appear if we ever can get a stale (zero
reference) locale pointer, but that doesn't seem to be the case (see the
previous comment in parens).
Thus, I was meaning to say that
--- src/locale_init.cc (revision 147329)
+++ src/locale_init.cc (working copy)
@@ -208,9 +208,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
locale::locale() throw() : _M_impl(0)
- __gnu_cxx::__scoped_lock sentry(get_locale_mutex());
_M_impl = _S_global;
looks safe apart on architectures where the pointer read can ever return
partially updated values (none I know has this problem).
I should scroll down - ignore my comments.
:) In any case, before attempting anything here, I recommend also re-analyzing libstdc++/12658.
(In reply to comment #4)
> Hm. I wonder how the "global" locale is supposed to interact with multiple
> threads anyway (in the face of C++ not knowing about threads). Would it be
> a conforming implementation to put the global locale into thread-local storage
> (thus, having a "global" locale for each thread)?
Pre C++0x, the standard says nothing about threads at all.
The C++0x draft has this to say:
Whether there is one global locale object for the entire program or one global locale object per thread is implementation defined. Implementations are encouraged but not required to provide one global locale object per thread. If there is a single global locale object for the entire program, implementations are not required to avoid data races on it
Benjamin, do you have a strong opinion about this issue? I don't, really, but especially in the light of the C++0x drafts (thanks to Greg for pointing it out), I would close for now the issue with a patch adding a configure time option to not use the mutex, the current safe but slow behavior as default, probably.
If I'm not mistaken, in either case the *.so would be binary compatible anyway.
In the future, we should probably move to the one global locale per thread, but I don't think it's easily implementable without affecting the ABI...
Subject: Bug 40088
Date: Fri Dec 18 09:41:03 2009
New Revision: 155342
2009-12-18 Jimmy Guo <firstname.lastname@example.org>
* src/locale_init.cc (locale::locale()): Optimize the common case
where _S_global still points to _S_classic.
David, I committed a patch which should alleviate the problem, any chance you can tell us whether you are seeing an improvement?
More tweaks (within the C++0x model still) are possible, but seems hard to implement without breaking the (generalized) ABI compatibility:
I meant C++03, sorry.
I think this PR can be closed: if the program doesn't change the global locale the mutex is not used anymore, is only incremented a reference count. As an enhancement we can do better, indeed, but the issues are known by now.
*** Bug 260998 has been marked as a duplicate of this bug. ***
Seen from the domain http://volichat.com
Marked for reference. Resolved as fixed @bugzilla.