Re: [patch] spinlocks: remove 'volatile'

From: Chase Venters
Date: Thu Jul 06 2006 - 14:15:26 EST


On Thu, 6 Jul 2006, linux-os \(Dick Johnson\) wrote:


On Thu, 6 Jul 2006, Linus Torvalds wrote:



On Thu, 6 Jul 2006, Linus Torvalds wrote:

Any other use of "volatile" is almost certainly a bug, or just useless.

Side note: it's also totally possible that a volatiles _hides_ a bug, ie
removing the volatile ends up having bad effects, but that's because the
software itself isn't actually following the rules (or, more commonly, the
rules are broken, and somebody added "volatile" to hide the problem).

That's not just a theoretical notion, btw. We had _tons_ of these kinds of
"volatile"s in the original old networking code. They were _all_ wrong.
Every single one.

Linus


Linus, you may have been reading too many novels.

If I have some code that does:

extern int spinner;

funct(){
while(spinner)
;

The 'C' compiler has no choice but to actually make that memory access
and read the variable because the variable is in another module (a.k.a.
file).

However, if I have the same code, but the variable is visible during
compile time, i.e.,

int spinner=0;

funct(){
while(spinner)
;

... the compiler may eliminate that code altogether because it
'knows' that spinner is FALSE, having initialized it to zero
itself.

Since spinner is global in scope, somebody surely could have
changed it before funct() was even called, but the current gcc
'C' compiler doesn't care and may optimize it away entirely. To
prevent this, you must declare the variable volatile. To do
otherwise is a bug.

No. The compiler can only optimize away that loop if spinner is provably const. Otherwise, _all_ non-const global variables would need to be declared 'volatile' because (as you imply) the compiler could forever assume their initial state has not changed.

Try it. Examine the -s. The loop is always present for me, even with -O3. Now, you'll notice that without a barrier, the value first loaded into the register
is never reloaded, making an infinite loop. But we know the compiler makes such optimizations, which is why we tell the compiler that the value should not be cached across the magic (barrier()) line.

Reading between the lines of your text, you are trying to say
that object 'spinner' should remain an integer, but any access
should be cast, like:

funct() {
while((volatile)spinner)
;

This is just a matter of style. It substitutes a number of casts
for a simple declaration. That said, I think that the current
implementation of 'volatile' is broken because the compiler
seems to believe that the variable has moved! It recalculates
the address of the variable as well as accessing its value.
This is what makes the code generation problematical.


Thanks,
Chase
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/