Boost logo

Boost Users :

Subject: Re: [Boost-users] [thread] variables in thread examples require 'volatile'?
From: OvermindDL1 (overminddl1_at_[hidden])
Date: 2009-12-07 22:35:56


On Mon, Dec 7, 2009 at 8:16 PM, Stonewall Ballard <sb.list_at_[hidden]> wrote:
>
> On Dec 7, 2009, at 7:56 PM, Steven Watanabe wrote:
>
>> AMDG
>>
>> Gabriel Redner wrote:
>>> I'm involved in a bit of a dispute in which a colleague is claiming
>>> that 'volatile' is necessary to make certain synchronization patterns
>>> correct.  As part of my response I pointed out that the boost.thread
>>> examples don't use it, but he maintains his position - saying that the
>>> examples are flawed.  I'm frankly somewhat out of my element here, and
>>> I'd like to get input from people who have presumably thought about
>>> this stuff a good deal.
>>>
>>> The example in question is here, under "synopsis":
>>> http://www.boost.org/doc/libs/1_41_0/doc/html/thread/synchronization.html#thread.synchronization.condvar_ref
>>>
>>> The claim is that 'volatile' is needed on the boolean, otherwise the
>>> compiler might cache the boolean in a register, and the loop would
>>> never exit.  He cites for support two articles:
>>>
>>> http://www.ddj.com/cpp/184403766
>>> https://www.securecoding.cert.org/confluence/display/seccode/DCL17-C.+Beware+of+miscompiled+volatile-qualified+variables
>>>
>>> Who's right?
>>>
>>
>> volatile is not needed in that example because access is protected by a mutex.
>>
>
> In this example:
> ----
> boost::condition_variable cond;
> boost::mutex mut;
> bool data_ready;
>
> void process_data();
>
> void wait_for_data_to_process()
> {
>    boost::unique_lock<boost::mutex> lock(mut);
>    while(!data_ready)
>    {
>        cond.wait(lock);
>    }
>    process_data();
> }
> ----
>
> What prevents the compiler from leaving data_ready in a register while in the while loop, hence never seeing some other thread setting it? The mutex is released while waiting on the condition, so data_ready is not protected while in cond.wait().

I might agree. Although I doubt volatile is the best thing here
either. Volatile may prevent it from being stored in registers, but
it will not prevent it from being cached. data_ready will eventually
be ready when the cache's finally sync, but you should be using a
condition variable instead of a global bool if you want it to happen
more along the lines of 'now'. It is possible that the cond.wait may
introduce a memory barrier that forces the cache among multiple CPU's
to sync up though, meaning that the code could actually be correct.
Hmm, now that I think of it, I think that example is correct. I see
no problem then.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net