Re: questions about memory_order_seq_cst fence



Joshua Maurice <joshuamaurice@xxxxxxxxx> writes:

We already know that the fence in thread 3 precedes the fence in thread
1 in S.

29.3p7 of N3290 says:

"For atomic operations A and B on an atomic object M, if there are
memory_order_seq_cst fences X and Y such that A is sequenced before X, Y
is sequenced before B, and X precedes Y in S, then B occurs later than A
in the modification order of M."

In our case, the fence in thread 3 occurs before the fence in thread 1
in S. The fence in thread 3 is thus X, the fence in thread 1 Y, the read
from x in thread 3 is A and the read from x in thread 1 is B.

Thus the read of x in thread 1 must occur later in the modification
order of x than the read in thread 3. Since the read in thread 3 is of
the last store to x (1), the read in thread 1 must also read that value,
and r1 == 1.

I disagree with this. I think you made the same mistake which I made
in my first post of this thread. Only /modifications/ appear in a
modification order. Reads do not appear in the modification order. At
least, this is the simple reading of 1.10 / 7, and its name is
"modification order", not "access order". Also note that the
definition of a "release sequence" in 1.10 / 8 does not make sense if
reads may appear in modification orders. Also note that the definition
of "visible sequence of side effects" in 1.10 / 14 does not make sense
if reads may appear in modification orders. (Note that there's some
ambiguity w.r.t. volatile atomic objects, as volatile reads do count
as side effects, but non-volatile reads AFAIK are not side effects.)

I used "modification order" here because that is what is used in
29.3p7. I realise that this has caused confusion because reads are
indeed not included in the modification order.

As I'm beginning to understand this, there is a typo in 29.3 / 7.

Agreed.

I think it's meant to read:
[]
For atomic **write (and atomic read-modify-write operations)** A and B
on an atomic object M, if there are memory_order_seq_cst fences X and
Y such that A is sequenced before X, Y is sequenced before B, and X
precedes Y in S, then B occurs later than A in the modification order
of M.
[/]

When we drafted this words, I think we meant "operation". It is the
reference to "modification order" that is the typo. What is meant is
that if A is a write and B is a read then B must read the value written
by A, or something later in the modification order; if A is a write and
B is a write then B must be later than A in the MO; if A is a read and B
is a write then A must read a value prior to B in the MO, and if A is a
read and B is a read then B must read the same value as A or a value
later in the MO.

It is based on this understanding that I applied my reasoning. It is
of course possible that I have misremembered the discussions of the
concurrency working group.

After rereading this section of the standard several times, I'm no
longer sure. I'll have to check my notes.

I'm still dealing with the implication that A precedes B in the total
order S of seq_cst operations does not imply that A happens-before B
nor A inter-thread happens before B nor A synchronizes-with B - and
that's irritating and slightly surprising. At least, I haven't yet
found a rule which states that, and I've looked decently hard, and
I've even found a note saying as much in 29.3 / 8.

You're right there. Note that 29.3p4-7 explicitly apply to **fences**,
so plain memory_order_seq_cst operations do not impose any ordering on
other operations beyond what they would if they were
acquire/release/acq_rel as appropriate.

Anthony
--
Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/
just::thread C++0x thread library http://www.stdthread.co.uk
Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
.