Re: [PATCH] "volatile considered harmful", take 3

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Bodo,

On 5/13/07, Bodo Eggert <[email protected]> wrote:
Satyam Sharma <[email protected]> wrote:

> In fact you can't really say the same for
> volatile. We already assume the compiler _actually_ took some
> pains to stuff meaning into C's (lack of) definition of volatile and
> implement it -- but in what sense, nobody knows (the C standard
                                                   ^^^^^^^^^^^^^^
> doesn't, so what are we).
  ^^^^^^^
It does:

I don't think so ... the ambiguity in 6.7.3:6 is why.

ISO/IEC 9899:1999 (E)

5.1.2.3 Program execution

5 The least requirements on a conforming implementation are:
 At sequence points, volatile objects are stable in the sense that previous
 accesses are complete and subsequent accesses have not yet occurred.

Worthy goal, indeed, but you've yourself pointed out later in your mail
why this may not be possible for a compiler/assembler to guarantee safely
(in a sense that the programmer usually wants, anyway), even with the C
standard-blessed "volatile" type-qualifier, what with the *hardware*
optimizing memory accesses _independently_ at a granularity finer than
the "sequence points" understood by a compiler.

9 Alternatively, an implementation might perform various optimizations
 within each translation unit, such that the actual semantics would agree
 with the abstract semantics only when making function calls across
 translation unit boundaries. In such an implementation, at the time of each
 function entry and function return where the calling function and the
 called function are in different translation units, the values of all
 externally linked objects and of all objects accessible via pointers
 therein would agree with the abstract semantics. Furthermore, at the time
 of each such function entry the values of the parameters of the called
 function and of all objects accessible via pointers therein would agree
 with the abstract semantics. In this type of implementation, objects
 referred to by interrupt service routines activated by the signal function
 would require explicit specification of volatile storage, as well as other
 implementation-defined restrictions.


6.7.3 Type qualifiers

6 An object that has volatile-qualified type may be modified in ways unknown
 to the implementation or have other unknown side effects. Therefore any
 expression referring to such an object shall be evaluated strictly according
 to the rules of the abstract machine, as described in 5.1.2.3. Furthermore,
 at every sequence point the value last stored in the object shall agree with
 that prescribed by the abstract machine, except as modified by the unknown
 factors mentioned previously.114) What constitutes an access to an object
 that has volatile-qualified type is implementation-defined.

The way I read it, "What constitutes an access to an object that has
volatile-qualified type is implementation-defined" is the standard's way
of saying: "All bets are off." Actually I wonder how the various _compiler
implementations_ read this clause (and whether *all* of them read it
consistently and equally, which is what a portable codebase probably
wants), because _their_ interpretation of this clause is more important
than mine, after all. But I don't really see how generic C code that uses
"volatile" can also claim dialect-independence.

So, IMO, the trouble with the volatile type-qualifier is that it is (what
should have been defined as in the first place, and what is in effect)
a _compiler extension_ *masquerading* as a _language keyword_.

*Unfortunately* (the trouble with C itself, is that a *committee* has made
it into ... something ... that it should not have made it into) -- anyway,
unfortunately C took it upon itself to solve a problem that it did not
have (and does not even bring about) in the first place: and the
half-hearted (or vague, call it what you will) attempt _then_ ends up
being a problem -- by making people _feel_ as if they are doing things
right, when that is probably not the case.

[ And we've not even touched the issue of whether the _same_ compiler's
implementation of volatile across archs/platforms is consistent. ]

It does not guarantee ordering or consistency beyond the scope of the
assembler layer, especially the CPU or other hardware may be free to cache
or reorder load/stores to these volatile objects (see e.g. MTRR), which is
why you'll usurally want to use something completely different. If you know

Exactly. So this combined with the issue above, is the last nail in volatile's
coffin as far as I'm concerned.

an object to not be modified from outside the scope of the C state machine
and it does not have relevant side effects, you can however use volatile
(likely on an atomic value).

Yes, but I'd prefer to stick to the straight-and-narrow (well-defined-and-
well-understood), and avoid volatile altogether. The kernel codebase does
contain APIs that allow one to avoid it and are also what one probably
wants for most situations.

I think you should say something like:

1) Don't use volatile
2) Read memory-barriers.txt carefully!
3) If you still use volatile, explain
  a) Why it's nescensary
  b) Why it's enough (see (2))
 to specify volatile on that object. Be sure to consider hardware cache and
 reordering, as well as prohibited optimizations on volatile access and on
 functions possibly doing volatile access.

Yeah, I agree with the wording above, also with Jimmy's summary that Jeff
and Peter agreed to already.

Satyam
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux