On Wed, Sep 5, 2012 at 10:52 AM, Martin Sebor <[email protected]> wrote:
> You're right that there is a race here. But the race is benign
> because the T2 will assign the same value to the string as T1
> did (because the grouping must be the same in the same locale).
> This doesn't reallocate the string but simply overwrites each
> byte with its own value. On all architectures we support this
> is atomic and safe.
OK so I did a little bit of testing, after looking at the *right*
__rw_guard class. :-)
I changed the std::numpunct class thusly:
template <class _CharT>
class numpunct : public _RW::__rw_facet
{
public:
// [ ... snip, no changes here ... ]
private:
int _C_flags; // bitmap of "cached data valid" flags
string _C_grouping; // cached results of virtual members
string_type _C_truename;
string_type _C_falsename;
char_type _C_decimal_point;
char_type _C_thousands_sep;
mutable _RW::__rw_mutex _C_object_mutex; // <-----
};
And then:
template <class _CharT>
inline string numpunct<_CharT>::grouping () const
{
if (!(_C_flags & _RW::__rw_gr)) {
_RWSTD_MT_GUARD (_C_object_mutex);
// double-test here to avoid re-writing an already written string
if (!(_C_flags & _RW::__rw_gr)) {
numpunct* const __self = _RWSTD_CONST_CAST (numpunct*, this);
// [try to] get the grouping first (may throw)
// then set a flag to avoid future initializations
__self->_C_grouping = do_grouping ();
__self->_C_flags |= _RW::__rw_gr;
}
}
return _C_grouping;
}
same changes for std::numpunct<>truename() and std::numpunct<>::falsename().
Ran 22.locale.numpunct.mt with the default values for nthreads and nloops.
Yesterday's test results, with the static per-class mutex:
# INFO (S1) (10 lines):
# TEXT:
# COMPILER: Intel C++, __INTEL_COMPILER = 1210,
__INTEL_COMPILER_BUILD_DATE = 20111011, __EDG_VERSION__ = 403
# ENVIRONMENT: pentiumpro running linux-elf (Fedora release 17 (Beefy
Miracle) (3.5.0-2.fc17.x86_64)) with glibc 2.15
# FILE: 22.locale.numpunct.mt.cpp
# COMPILED: Sep 4 2012, 09:11:36
# COMMENT: thread safety
############################################################
# CLAUSE: lib.locale.numpunct
# NOTE (S2) (5 lines):
# TEXT: executing "locale -a > /tmp/tmpfile-V7siTq"
# CLAUSE: lib.locale.numpunct
# FILE: process.cpp
# LINE: 276
# INFO (S1) (3 lines):
# TEXT: testing std::numpunct<charT> with 8 threads, 200000 iterations
each, in 32 locales { "C" "aa_DJ" "aa_DJ.iso88591" "aa_DJ.utf8"
"aa_ER" "aa_ER@saaho" "aa_ER.utf8" "aa_ER.utf8@saaho" "aa_ET"
"aa_ET.utf8" "af_ZA" "af_ZA.iso88591" "af_ZA.utf8" "am_ET"
"am_ET.utf8" "an_ES" "an_ES.iso885915" "an_ES.utf8" "ar_AE"
"ar_AE.iso88596" "ar_AE.utf8" "ar_BH" "ar_BH.iso88596" "ar_BH.utf8"
"ar_DZ" "ar_DZ.iso88596" "ar_DZ.utf8" "ar_EG" "ar_EG.iso88596"
"ar_EG.utf8" "ar_IN" "ar_IN.utf8" }
# CLAUSE: lib.locale.numpunct
[ ... ]
# +-----------------------+----------+----------+----------+
# | DIAGNOSTIC | ACTIVE | TOTAL | INACTIVE |
# +-----------------------+----------+----------+----------+
# | (S1) INFO | 11 | 11 | 0% |
# | (S2) NOTE | 1 | 1 | 0% |
# | (S8) ERROR | 0 | 3 | 100% |
# | (S9) FATAL | 0 | 1 | 100% |
# +-----------------------+----------+----------+----------+
real 2139.31
user 2406.09
sys 155.61
=======================================
Today's test results with the per-object mutex (as shown above):
# INFO (S1) (10 lines):
# TEXT:
# COMPILER: Intel C++, __INTEL_COMPILER = 1210,
__INTEL_COMPILER_BUILD_DATE = 20111011, __EDG_VERSION__ = 403
# ENVIRONMENT: pentiumpro running linux-elf (Fedora release 17 (Beefy
Miracle) (3.5.0-2.fc17.x86_64)) with glibc 2.15
# FILE: 22.locale.numpunct.mt.cpp
# COMPILED: Sep 5 2012, 13:08:03
# COMMENT: thread safety
############################################################
# CLAUSE: lib.locale.numpunct
# NOTE (S2) (5 lines):
# TEXT: executing "locale -a > /tmp/tmpfile-ww0nez"
# CLAUSE: lib.locale.numpunct
# FILE: process.cpp
# LINE: 276
# INFO (S1) (3 lines):
# TEXT: testing std::numpunct<charT> with 8 threads, 200000 iterations
each, in 32 locales { "C" "aa_DJ" "aa_DJ.iso88591" "aa_DJ.utf8"
"aa_ER" "aa_ER@saaho" "aa_ER.utf8" "aa_ER.utf8@saaho" "aa_ET"
"aa_ET.utf8" "af_ZA" "af_ZA.iso88591" "af_ZA.utf8" "am_ET"
"am_ET.utf8" "an_ES" "an_ES.iso885915" "an_ES.utf8" "ar_AE"
"ar_AE.iso88596" "ar_AE.utf8" "ar_BH" "ar_BH.iso88596" "ar_BH.utf8"
"ar_DZ" "ar_DZ.iso88596" "ar_DZ.utf8" "ar_EG" "ar_EG.iso88596"
"ar_EG.utf8" "ar_IN" "ar_IN.utf8" }
# CLAUSE: lib.locale.numpunct
[ ... ]
# +-----------------------+----------+----------+----------+
# | DIAGNOSTIC | ACTIVE | TOTAL | INACTIVE |
# +-----------------------+----------+----------+----------+
# | (S1) INFO | 11 | 11 | 0% |
# | (S2) NOTE | 1 | 1 | 0% |
# | (S8) ERROR | 0 | 3 | 100% |
# | (S9) FATAL | 0 | 1 | 100% |
# +-----------------------+----------+----------+----------+
real 2416.75
user 2694.64
sys 159.49
--
Stefan Teleman
KDE e.V.
[email protected]