[cpp-threads] Alternatives to SC

Paul E. McKenney paulmck at linux.vnet.ibm.com
Wed Jan 17 17:23:36 GMT 2007


On Tue, Jan 16, 2007 at 05:05:16PM -0800, Chris Thomasson wrote:
> From: "Paul E. McKenney" <paulmck at linux.vnet.ibm.com>
> To: "C++ threads standardisation" <cpp-threads at decadentplace.org.uk>
> Sent: Tuesday, January 16, 2007 9:46 AM
> Subject: Re: [cpp-threads] Alternatives to SC

Hello, Chris,

> [...]
> 
> >>
> >>P1: x = 1;
> >>P2: if (x == 1) eieio(), y = 2;
> >>P3: if (y == 2) isync(), assert(x == 1);
> [...]
> 
> Here is a trick you can do on the x86:
> 
> vars A=0, B=0, C=0, X=9, Y=9, Z=9;
> fence var Fence;
> 
> CPU1: A=1; B=2; C=3; Fence=1
> CPU2: if(Fence==1) X=1; Y=2; Z=3; Fence=2
> CPU3: if(Fence==2) {
>  assert(A==X);
>  assert(B==Y);
>  assert(C==Z);
> }
> 
> This will not assert on the current x86 because its stores/loads are as
> follows:
> 
> // store
> void atomicword_store(void **p, void *w) {
>  membar #LoadStore | #StoreStore
>  *p = w;
> }

OK.

> // load
> void* atomicword_load(void **p) {
>  void *w = *p;
>  membar #LoadStore | #LoadLoad;
>  return w;
> }

The above is indeed true on a number of x86 implementations, but is
-not- reflected in the architecture.  See for example the AMD x86-64
Architecture Programmer's Manual Volume 2 (System Programming),
24593-Rev.3.07-Sep-2002, page 195, first bullet:

	Out-of-order reads are allowed.  Out-of-order reads can occur
	as a result of out-of-order execution or speculative execution.
	The processor can read memory out-of-order to allow out-of-order
	execution to proceed.

There are also a number of Intel manuals containing the words
"Reads can be carried out speculatively and in any order".

So there is no guarantee of #LoadLoad across all x86 implementations,
even if a number of very popular x86 implementations do in fact provide
this guarantee.

							Thanx, Paul

> Which means:
> 
> vars A=0, B=0, C=0, X=9, Y=9, Z=9;
> fence var Fence;
> 
> CPU1: A=1; B=2; C=3; Fence.rel=1
> CPU2: if(Fence.acq==1) X=1; Y=2; Z=3; Fence.rel=2
> CPU3: if(Fence.acq==2) {
>  assert(A==X);
>  assert(B==Y);
>  assert(C==Z);
> }
> 



More information about the cpp-threads mailing list