[cpp-threads] Yet another visibility question

Boehm, Hans hans.boehm at hp.com
Thu Dec 21 01:26:51 GMT 2006


> From:  Doug Lea
> 
> Boehm, Hans wrote:
> 
> > Con (a showstopper, I think): We don't know how to express 
> > dependency-based ordering in a way that's not broken by 
> conventional 
> > optimizations on other compilation units that don't mention 
> atomics, 
> > and remains usable of the store takes place on the far side of an 
> > abstraction boundary.
> >
> 
> 
> Of the use cases for raw operations, it seems that the most 
> defensible one is hand-crafted speculation. As in (for an atomic x)
> 
> int rawx = x.load_raw();
> int nextx = f(rawx)
> if (x.cas(rawx, nextx)) return;
> // else maybe get a lock and do it the slow way
> 
> Since speculation is at the mercy of whatever happens, you 
> don't expect very much. But you do expect that the load_raw 
> actually reads x, and isn't completely optimized away and 
> replaced by say, 0.
> 
> So perhaps the place to start is to require that raw loads 
> and stores must at least actually occur (unlike ordinary 
> variables where dead ones can be killed).
> Except that loads could be killed if it is provable that 
> across all executions of the program, the same value must be read.
> 
> This sounds sorta like rules for old-style C volatiles?
> 
> You can probably go a little further by somehow saying that 
> the loads/stores must occur between any surrounding full 
> barriers that might exist. As in, not moving across lock boundaries.
> 
> How much more do you need?
> 
The major concern is that the unordered atomic equivalent of

Thread 1: r1 = x; y = 1
Thread 2: r2 = y; x = 1

should allow r1 = r2 = 1, while

Thread 1: r1 = x; y = r1
Thread 2: r2 = y; x = r2

should not, since that would admit out-of-thin-air values, which we may
not want to allow.

As Peter points out, it's not 100% clear that we want to prohibit "out
of thin air" values.  It would still be nice to be able to prove that
f() below returns 0, no matter what foo does.

int f() {
   int x = 0;
   int *y = foo();

   *y = 13;
   return x;
}

I think currently that's violated only for implementations of foo() that
exhibit undefined semantics.  If we allow out of thin air values, foo()
could return &x, and legitimate programs could return nonzero from f(),
which argues that some tools might have to consider the possibility.
Presumably, none of this could happen in a real implementation, which
argues that this would be a weird behavior to standardize.

Hans



More information about the cpp-threads mailing list