On Wed, Sep 5, 2012 at 10:52 AM, Martin Sebor <mse...@gmail.com> 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. stefan.tele...@gmail.com