J
Joshua Maurice
Am 07.07.2012 01:58, schrieb Joshua Maurice:
No, this is misleading. volatile alone is not sufficient to warrant data
consistency between threads, but is necessary. volatile and _Atomic are
complementary specifications that *both* are needed if you want to make
sure that a thread always uses the latest stored value of a variable. If
you have
static int _Atomic a = ATOMIC_VAR_INIT(23);
if (tester)
for (; printf("current value is %d\n", a);
The compiler is allowed to change the loop into something equivalent to
{
int tmp = a; // do an atomic_load operation here
for (; printf("current value is %d\n", tmp);
}
and thus always print the same value.
static int _Atomic volatile a = ATOMIC_VAR_INIT(23);
would assure that each execution of printf would see an updated value.
(Let's assume you were talking about C11.) You are simply wrong. That
is not what the standard says. This is not what people on the
standards committee are saying. That is not what compile writers are
implementing. This is not what the experts are saying. volatile is
useless for threading code by the C11 standard. Entirely useless for
inter-thread communication.
However, having said that, your example is an interesting one. The
specific rule which disallows the above compiler transformation is an
obscure one, and not one of my favorites. I've tried to discuss this
very issue on comp.std.c++, with no replies IIRC. C11 threading, being
largely just a copy of C++11 threading, has the rule in question. In
the draft I have lying around of C11, n1570, the rule is:
n1570: 7.17.3 Order and consistency / 16
Implementations should make atomic stores visible to atomic loads
within a reasonable amount of time.
That rule disallows the above transformation. The only reasonable
reading of that rule is to prevent compiler transformations like the
one above.
There's also one other new obscure rule, again copied from C++11 to
C11, which has some relevance here.
n1570: 6.8.5 Iteration statements / 6
An iteration statement whose controlling expression is not a constant
expression, that performs no input/output operations, does not access
volatile objects, and performs no synchronization or atomic operations
in its body, controlling expression, or (in the case of a for
statement) its expression-3, may be assumed by the implementation to
terminate.
This generated a lot of discussion on the C++ newsgroups. In short,
this says:
is now undefined behavior. I think I dislike the wording of this onefor(;;
even more than the earlier rule. However, going with the "spirit" of
this rule, I might argue that above compiler transformation is
disallowed; if you're not allowed to make a non-terminating loop with
a constant controlling expression, then the compiler probably
shouldn't be allowed to make one either. Still, I want to emphasize
that reading is merely IMHO, whereas "7.17.3 Order and consistency /
16" much less ambiguously disallows the above compiler
transformation.
For further reading, see:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2016.html
http://msdn.microsoft.com/en-us/library/12a04hfd.aspx
http://kernel.org/doc/Documentation/volatile-considered-harmful.txt
http://software.intel.com/en-us/blo...lmost-useless-for-multi-threaded-programming/
http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
http://kerneltrap.org/Linux/Volatile_Superstition
The C++11 and C11 standards.