stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Martin Sebor <se...@roguewave.com>
Subject Re: thoughts on STDCXX-452 -- std::numpunct not thread safe
Date Wed, 26 Sep 2007 18:55:05 GMT
Travis Vitek wrote:
[...]
> I think the easiest solution is to assign the cached value and modify
> the bitmask under the same lock.

Yes, that's much better (more efficient) than what I suggested.

> 
> template <class _CharT>
> inline _TYPENAME numpunct<_CharT>::char_type
> numpunct<_CharT>::decimal_point () const
> {
>     if (!(_C_flags & _RW::__rw_dp)) {
> 
>         numpunct* const __self = _RWSTD_CONST_CAST (numpunct*, this);
> 
>         const char_type __tmp = do_decimal_point ();
> 
>         // call virtual outside lock because it may acquire the same
>         // lock internally and we want to avoid a recursive acquire.
>         _RWSTD_MT_GUARD (__self->_C_lock);
> 
>         // ithis conditional isn't strictly necessary and could be
>         // omitted.
>         if (!(_C_flags & _RW::__rw_dp)) {
> 
>             // [try to] get the decimal point first (may throw)
>             // then set a flag to avoid future initializations
>             __self->_C_decimal_point  = __tmp;
>             __self->_C_flags         |= _RW::__rw_dp;
> 
>         }
>     }
> 
>     return _C_decimal_point;
> }
> 
> Intel Thread Checker continues to complain about the outer if accessing
> _C_flags, but I'm pretty sure that this code is safe.

Agreed.

> The only problem I
> can think of is that the compiler or runtime system does some
> instruction reordering or something like that [it's a possibility]. I
> worry that the optimizer will think that __tmp is actually not really
> necessery and will optimize it out, choosing to write directly to
> __self->_C_decimal_point outside the lock. 

Theoretically, it is possible, because the compiler need not know
that _RWSTD_MT_GUARD (__self->_C_lock) is the same as
pthread_mutex_lock(). (If it were the latter, the compiler is
prohibited from move code above the call, although it might be
allowed to move code below it.)

But when the compiler can't tell whether a function call contains
a hidden call to pthread_mutex_lock() it must assume that it does
and avoid moving any code.

Martin

Mime
View raw message