[cpp-threads] Causality on more than two processors, write atomicity

Alexander Terekhov alexander.terekhov at gmail.com
Wed Sep 7 21:03:44 BST 2005


On 9/7/05, Herb Sutter <hsutter at microsoft.com> wrote:
[...]
>  int x, y;
> 
>  start: x == y == 0;
>  invariant: x <= y <= x+1

Could it be that "-1" managed to escape once again?

> 
>  P0: if( cas( &x, 0, 0 ) ) x = 1;
>  P1: if( cas( &x, 1, 1 ) ) y = 2;
>  P2: assert( invariant );

_y = y.load(msync::hlb); _x = x.load(msync::naked_competing);
assert(invariant(_x, _y));

or

_y = y.load(msync::naked_competing); _x = x.load(msync::slb);
assert(invariant(_x, _y));

> 
> Now certainly the invariant never breaks for P2 (under a sane memory
> model, including the JMM), right? 

That depends on msync::hsb/msync::cchsb fencing inside/around cas(). IIRC,
revised JLS Chapter 17 says nothing about cas(). 

> Similarly, it seems to me that
> 
>  if( var < value ) // or any other nonequal comparison
>    ...
> 
> could be transformed to
> 
>  lvar = var;
>  if( lvar < value )
>   if( cas( &var, lvar, lvar ) )

I'd rather simply do an 

   if (ia32_lock_cmpxchg(&var, 42, 42) < value) //
InterlockedCompareExchange() aside for a moment

It certainly looks fancier.

<quote source =  Intel's CMPXCHG Description>

The destination operand is written back if the comparison fails; 
otherwise, the source operand is written into the destination. 
(The processor never produces a locked read without also 
producing a locked write.)

</quote>

I suspect that

 if( ia32_lock_xadd(&var, 0) < value )

will also work, but I'm somewhat missing strong language about 
mandatory write as in CMPXCHG.

Hello Intel, anyone at home?

http://groups.google.ca/group/comp.arch/msg/b6c686b7d827022c
http://groups.google.ca/group/comp.arch/msg/d532441a875bc4fc

regards,
alexander.




More information about the cpp-threads mailing list