Boost logo

Boost :

From: Andreas Huber (ahd6974-spamgroupstrap_at_[hidden])
Date: 2007-02-05 16:37:00


Steven Watanabe wrote:
> AMDG
>
> Andrey Semashev <andysem <at> mail.ru> writes:
>
>>
>> I guess the only way to safely initialize a static local variable is
>> through some call_once concept implementation. The problem in my case
>> is that I'd like the library to be as light as possible and as fast
>> as possible, so I can't make use of Boost.Thread for now.
>>
>
> I believe that volatile works just as well here
> as it does for m_StatesInfo.
>
> template<class Dispatcher>
> struct static_event_dispatcher {
> static volatile bool initialized;
> //Dispatcher must have a trivial default constructor
> static Dispatcher dispatcher;
> static Dispatcher& value() {
> if(!initialized) {
> const_cast<volatile Dispatcher&>(dispatcher).init();
> initialized = true;
> }
> return(dispatcher);
> }
> };
>
> template<class Dispatcher>
> static volatile bool static_event_dispatcher<Dispatcher>::initialized
> = 0; template<class Dispatcher>
> static Dispatcher static_event_dispatcher<Dispatcher>::dispatcher;

As Andrei Alexandrescu explains in the following article:

http://www.ddj.com/dept/cpp/184403766

a volatile-declared variable of primitive type only hinders the compiler
to cache its value in a processor register. It doesn't prevent any race
conditions in an MT application. In your code one thread can be in the
middle of executing init() when another thread evaluates the condition
in the if statement. Clearly, this will lead to two threads calling
init(), possibly even at the same time.

Even if you rewrite the code as follows

       // above same as before
       if(!initialized) {
           initialized = true;
           const_cast<volatile Dispatcher&>(dispatcher).init();
       }
       // below same as before

there's still a race condition. Two threads could evaluate initialized
at the same time... All this even ignores weaker memory models of SMP
machines where changes to initialized in one processor are not even
visible to threads running on another processor unless you use a memory
barrier.

-- 
Andreas Huber
When replying by private email, please remove the words spam and trap
from the address shown in the header. 

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk