[cpp-threads] "C++ threads standardisation" <cpp-threads@decadentplace.org.uk>

Nick Maclaren nmm1 at cus.cam.ac.uk
Sun Feb 19 17:29:10 GMT 2006


Oops.  Sorry.  That seems to have been forwarded twice.


> > I really DON'T like specifying that structure/array accesses
> > are accesses to the individual elements in some order.  In
> > the past, implementations have performed stores using
> > fast-path code, trapped failures, and repeated using safe
> > code.  That isn't unreasonable, and is seriously handicapped
> > by that specification.
> >
> > [ Examples snipped. ].
> 
> I don't yet understand why you think this is observable to the
> programmer.  If the accesses to the individual elements are not ordered,
> I think the implementation is still free to do everything you suggest.
> Certainly that was my intention.

Because, for __async volatile elements, the behaviour "store every
element exactly once in an indeterminate order" is distinguishable
from "store every element at least once in an indeterminate order"
by another thread.

> Agreed.  Thanks.  I added a note for now.  Clark Nelson is also working
> on a paper addressing the sequence point issues.  I'd be very happy if
> he got this at least mostly straightened out.

I have posted an example of my concerns to him.

> I actually no longer understand what the standard means here.

I never have known even what was intended, and have been involved since
the late 1980s.  If I recall, this was one of the reasons that the BSI
nearly voted "no" on C89.

>  Assume i
> is a local variable, and f stores through the pointer passed to it.
> 
> Which one of the following is legal?
> 
> (i = 13) + (i = 14)	-- no
> (i = 13) + f(&i)	-- not a clue
> f(&i) + f(&i)	-- yes, otherwise lots of stuff is broken
> 
> Probably the middle one should be undefined, but I have no idea how the
> standard implies that without also outlawing the last one.

Yes, indeed.  And try the following, too:

extern i = 0;
int fred (void) {++i; return 0;}
(0, i = 1, 0) + (0, i = 2, 0);
f() + f();

Trying to distinguish those is blenchworthy.

> > The communicates-with relation
> > ------------------------------
> >
> > Hmm.  Does this include I/O to external agents, signaling and so on?
> > Those are a real minefields, as they involve specifying the
> > behaviour of external entities, some of which may use
> > concepts that are not even describable in C++.
>
> That was the intent, at least to the extent that we want those to imply
> memory visibility.  I think the standard should confine itself to
> setting up the terminology, and defining the relation for routines in
> the standard library.  Other standards will have to address it for other
> libraries.  With luck, they'll borrow the terminology, so the result
> makes sense.

But remember that the standard library includes I/O, signals, etc.

> > Later, under the Java model, you mention I/O again.  There
> > are many reasons that I/O should NOT be included in the
> > normal total order, of which the above is one.  Another, and
> > much stronger, one is that is prevents even simple buffering
> > - let alone asynchronous I/O.
> > One needs a different set of definitions.
> 
> Remember that we effectively have a total order on ordinary memory
> operations only for defining when there is a data race.  If there is no
> data race, the ordering doesn't matter, because it's not observable.  If
> there is a data race, the ordering doesn't matter because the semantics
> are undefined.

I am afraid not.  C++ has both callbacks and the concept of streams
connecting to each other.  This means that actions that put data in
to a thread have an implied requirement to make it available at the
far end for the same or another thread to remove.  Unless specifically
allowed for, buffering often gets forbidden by accident.

> > With others (equally reasonable), I can produce just such examples.
> > In fact, some of the earlier ISO C compilers were changed to
> > NOT write padding characters, because they broke so many "working"
> > programs.
> 
> I'm not sure I understand what you're getting at here.

What I am saying is that there ARE reasonable interpretations where
implementations are allowed to write data into padding characters in
structures and unions.  The current wording is ambiguous so, if you
want to forbid it, you must do so explicitly.  I don't think that
anyone will scream, as there is now a consensus (whereas there was
not one back in the 1990s).

> I agree with you.  The HP/UX IA64 compiler actually gives you options to
> control fairly precisely what it should mean.  The Intel compiler also
> gives you a couple of different ones.  But in earlier discussions there
> seemed to be possibly a very weak consensus that it should provide
> guarantees corresponding to a weak interpretation of the standard, i.e.
> it should be OK to use volatiles to preserve variables across setjmp,
> and to protect against unexpected mmap-based aliasing.  And for
> performance reasons, it should do little else.
> 
> I'm not sure I read that correctly, and it may be the wrong thing to do.

I am sure that it is wrong, but it may be the best thing to do :-(

> People writing clever lock-free algorithms seem to sometimes like this
> interpretation, because they can then manually insert
> (machine-dependent) memory fences, and guarantee that volatile
> declarations slow down the code only as much as necessary.  That
> probably isn't a good argument, since it doesn't help for portable code.

Given the current wording, I would support deprecating volatile and/or
removing all wording on its semantic effects and saying that they
are implementation-defined.

Incidentally, the current wording DOESN'T protect against unexpected
mmap-based aliasing, and the liberty of setjmp/longjmp to corrupt
data is a mere sop to some incompetent implementations of the late
1980s.  Speaking as an implementor, it is false that it helps with
efficiency.


Regards,
Nick Maclaren,
University of Cambridge Computing Service,
New Museums Site, Pembroke Street, Cambridge CB2 3QH, England.
Email:  nmm1 at cam.ac.uk
Tel.:  +44 1223 334761    Fax:  +44 1223 334679



More information about the cpp-threads mailing list