[cpp-threads] RE: volatile, memory models, threads

Nick Maclaren nmm1 at cus.cam.ac.uk
Sat Mar 11 10:00:24 GMT 2006


"Boehm, Hans" <hans.boehm at hp.com> wrote:
> 
> The strawman proposal (revised after the C++ committee paper, and after
> the beginning of this discussion) now states:
> 
> "We define an execution to contain an inter-thread race if two threads
> perform two conflicting actions, neither happens-before the other, and
> at least one is not a synchronization action."
> 
> Thus there is clearly a race here, as there was always intended to be.
> 
> Does that resolve all concerns?

No, because your previous statement is false.  There is NOT "clearly"
a data race.  Let's tag the operations:

A:    Thread 1:    X = 0x1200
B:                 *(atomic *)X = 0X0034
C:    Thread 2:    *(atomic *)X = 0X0045

The point is that there IS no data race between the two threads, but
but only between the individual actions.  However, the standard also
requires that the effect of A not be visible.  The question is which
overrides the other.  But, in that simple case, let's say that we all
agree that it is undefined behaviour.  Try a variation:

      Initially:   X = 0x0000
A:    Thread 1:    if (X == 0X0045) X = 0x1200
B:                 *(atomic *)X = 0X0034
C:    Thread 2:    *(atomic *)X = 0X0045

There are no extra synchronisation actions, no extra standard-defined
(at present, i.e. single-thread) serialisation constraints, A remains
purely non-atomic, and yet no normal programmer will ever expect a
data race.  You may, I may, and many of the other posters to this list
may, but I assure you that we are freakish in that respect.  If you
have ever tried to explain how the above can be a data race to even
a very bright scientist, you will know what I mean.

My first example was purely for exposition, and was obviously a silly
bit of code.  But code of the sort in my second example is very common
indeed, usually in the form where the atomic actions are message
passing (including semaphores).  However, as soon as atomic primitives
are added (library OR language), people WILL use them in that way.
Dammit, many "lock-free" algorithms describe exactly WHICH of their
actions need to be made atomic for them to work!

My assertion is that allowing both atomic and non-atomic actions on
a single data object requires some complicated extra wording to draw
a line between defined and undefined uses, which is not there are
present.  My solution is simply to forbid such mixtures :-)


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