[concurrency-interest] shouldn't data race be specified in JMM for non-volatile conflicting accesses only?

Valentin Kovalenko valentin.male.kovalenko at gmail.com
Thu Dec 14 03:47:32 EST 2017


Hi everyone,

The way "data race" and "correctly synchronized" programs are defined in
JMM continue bothering me. It makes completely legit programs producing
consistent results with all shared variables declared volatile (see
Example2 below) to be "incorrectly synchronized" because data race
definition is equally applicable to plain and volatile accesses.

So my question is: shouldn't data race be specified in JMM for non-volatile
conflicting accesses only?

----------Explanation of my reasoning
JMM defines data race as follows:
*a) Two accesses to (reads of or writes to) the same variable are said to
be conflicting if at least one of the accesses is a write.*
*b) When a program [my remark: wrong; not a program, but an execution]
contains two conflicting accesses that are not ordered by a happens-before
relationship, it is said to contain a data race.*
(note how this is equally applicable to plain and volatile accesses.)

JMM defines a correctly synchronized program as follows:
*A program is correctly synchronized if and only if all sequentially
consistent executions are free of data races.*

--------------------Example1
May help with understanding Example2, but you can skip it if Example2 is
clear right away.
Let's consider the following program with two concurrently running threads
(t1 and t2):

static volatile int s = 0;// w0
t1: r = s;// r
t2: s = 1;// w1

Executions (e1 and e2) with the following two synchronization orders (SO)
are allowed by JMM (and there can't be any other SO orders):

SO1: w0, r, w1; which gives notHB(r, w1), notHB(w1, r), r == 0
SO2: w0, w1, r; which gives HB(w1, r), r == 1

Both executions are sequentially consistent by definition because all
actions are synchronization actions, hence ordered in a total order SO
which is consistent with program order (PO). But e1 has a data race because
r and w1 are not ordered by HB. Hence this program is not correctly
synchronized by definition despite the only shared variable we have here is
volatile s.

--------------------Example2
Now let's change the example a bit by forcing t1 to wait for w1 before
making a read r:

static volatile int s = 0 // w0
t1: while (s == 0);// r_i, where i is from [1, k], and k >= 1 and is finite
      r = s;// r
t2: s = 1 // w1

For this program, JMM allows the following execution e1 and a set of
analogous executions E2 with the following SO orders respectively (and
there can't be any other SO orders):

SO1: w0, w1, r_1, r; which gives HB(w1, r), r == 1
SO2: w0, r_1, ..., w1, ... r_k, r; which gives notHB(r_1, w1), notHB(w1,
r_1), HB(w1, r), r == 1

e1 and every execution from E2 are sequentially consistent by definition
because all actions are synchronization actions, hence ordered in a total
order SO which is consistent with program order (PO). But any execution
from E2 has a data race because at least r_1 and w1 are not ordered by
HB. *Hence
this program is not correctly synchronized by definition despite the only
shared variable we have here is volatile s, and all the outcomes of the
program are the same (r == 1).*

Regards,
Valentin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20171214/2431111e/attachment.html>


More information about the Concurrency-interest mailing list