[cpp-threads] Web site updated

Peter Dimov pdimov at mmltd.net
Tue Feb 13 22:21:29 GMT 2007


Boehm, Hans wrote:

> But I think that combining accesses can also be a problem at user
> level, for other reasons.  If I write
>
> Thread1:
> for(;;) {
>     a.store_relaxed(0); // or release
>     a.store_relaxed(1);
> }
>
> Thread2:
> while (a.load_relaxed());
> <do something useful>
>
> Should I expect thread 2 to eventually make progress?  Clearly if the
> first a.store_relaxed() is elided, the answer is no.  But an answer of
> "yes" is probably more desirable.

This is an interesting example since thread 1 can be equivalently 
transformed to

a.store_relaxed(0);

for(;;) {
    a.store_relaxed(1); // or release
    a.store_relaxed(0);
}

where combining the stores will give a different result. But does it 
correspond to a sensible real-world case?

Either way, my point is that we already have a "dumb mode" switch, it's 
called volatile. If a is marked volatile:

volatile int a;

for( ;; )
{
    atomic_store_relaxed( &a, 0 );
    atomic_store_relaxed( &a, 1 );
}

this gives the programmer the intended effects of a thread toggling a 
between 0 and 1. So this is one way to keep volatile and atomic separate and 
orthogonal. We already decided to not make volatile imply atomic, so it only 
makes sense to consistently apply this principle in the other direction and 
state that atomic does not necessarily imply volatile.

Or not. But I can see many optimization opportunities being lost. It would 
be rare for two relaxed accesses to appear next to one another in the source 
code, but inlining several functions and then reordering the basic block 
will routinely produce such examples. In fact, _release and _acquire will 
suffer even more because of the redundant barriers.




More information about the cpp-threads mailing list