[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