>Right after this I have to mention a few exceptions to the rule: there _are_
>two circumstances where using "volatile" is acceptable.
>
> 1) for a clock. Look at "jiffies". The whole _idea_ with a clock is that it
> changes, and it's _ok_. A clock is not a linked list or anything like that.
> 2) For accessing hardware registers internally. No kernel code should do it
> (they should use "readb()" etc that should take care of it), but in that
> context it's ok. Again, for the same reason as in (1) - it's not a data
> structure, it's just a very special "value".
volatile isn't even good enough for accessing hardware registers in a
portable way. It's sort of just like saying "please please please do
the right thing", which doesn't always work because "the right thing"
is not defined and compilers are free to do things that are "volatile"
but still not quite what you had in mind. Here are two things I have
seen go wrong when using various compilers:
1. "if (*(volatile long *)p & 1)" ... compiling to use
"testb $1,(p)", i.e., using a byte access instead of a long,
which fails if your hardware doesn't support byte accesses.
2. "*(volatile long *)p = constant" compiling (on a 16-bit
compiler) to
movw $(constant >> 16),(p+2)
movw $(constant & 0xFFFF),(p)
where in my case the hardware accepted word writes, but the
hi/lo order broke the code because it changed the semantics.
Sure, in Linux we can probably get away with using gcc's volatile
implementation for accessing hardware registers, but it's still a good
idea to make sure it "does the right thing" (which it does, for now).
As an aside, gcc's implementation of volatile at the RTL level will
not allow its instruction combiner to generate code like in case 1.
It's lousy code generation when confronted with "volatile" is a result
of breaking down each source expression into RISC-like steps called
RTL insns, then trying to combine them later, e.g., doing the RTL
equivalent of combining "movl (p),%reg" with "testl $1,%reg" to get
"testl $1,(p)". The problem is that RTL insns which were generated
from volatile expressions are not subject to instruction combination.
This could possibly be fixed by adding another field to each RTL insn
that says what source expression generated it, and allowing volatile
RTL insns to be combined if they were generated from the source
expression.
Tom.