Volatile variables in C!!

R

r_o_h_i_t

Can anybody please tell me the complete properties if volatile
variables in C. And what are specific uses of them?
Thanks in advance.
 
T

Tom St Denis

r_o_h_i_t said:
Can anybody please tell me the complete properties if volatile
variables in C. And what are specific uses of them?
Thanks in advance.

Do.

Your.

Own.

Homework.

Tom
 
R

Richard Heathfield

r_o_h_i_t said:
Can anybody please tell me the complete properties if volatile
variables in C.

This is the important one:

"An object that has volatile-qualified type may be modified in ways unknown
to the implementation or have other unknown side effects." (Taken from C99,
6.7.3(6))
And what are specific uses of them?

One fairly typical place in which you might need to use a volatile object
would be where you need to point to, say, a system clock. Imagine, for
example, an embedded system which has a particular 32-bits-wide memory
location containing the time, using 5 bits for the hours, 6 for the
minutes, 6 for the seconds, and - um - 15 for the 32768ths of a second. :)
The only support the implementation provides for the clock is a function
returning its address. Thus:

volatile unsigned long *sysclock = _GetSystemClockAddress();

Now, your code might have something to do which will only take a few
microseconds, but it wants to wait until a tick has just happened, so that
it can do <whatever> without having the clock change under it. It could do
something like this:

while(*sysclock == *sysclock)
{
continue;
}
/* the clock just ticked */

If sysclock were not volatile-qualified, the compiler would almost certainly
treat this as a forever-loop. Not good! But because it's
volatile-qualified, the compiler can't assume the value of *sysclock won't
change during the evaluation of the condition. So (modulo poor
explanations!) it not only has to read *sysclock every time it goes round
the loop, but it actually has to read it /twice/. The volatile keyword
forces this. Consequently, in this case, when the clock goes "tick", the
loop will end - assuming the processor is fast enough to catch a tick "in
progress" (If it isn't fast enough, we might just have a forever loop after
all. Embedded programming is harder than it looks.)
 
R

Randy Howard

Do.

Your.

Own.

Homework.

Tom

First of all, not everyone is still in college. Second, volatile
is probably one of the most understood and misapplied keywords
in the language. Discussing it here isn't a bad thing.

Richard gave a good short treatise on some of the uses of it.

Slightly OT: Anyone that has spent much time reading
comp.programming.threads has seen thousands of words on the topic,
most of which are based upon *false* assumptions about volatile being
a safe replacement for mutexes or other more expensive locking
primitives.

In a sense, volatile is a useful, standardized way of handling non-
standard platform specific extensions. :)

H&S 5th Ed covers this in more than the usual amount of detail in
section 4.4.5.

K&R2 says that declaring an object volatile "announces that it
has special properties relevant to optimization". It also talks
separately about its use for memory-mapped I/O to device registers,
which I think proves it's usefulness for platform-specific code.
 
C

CBFalconer

Richard said:
.... snip ...

while(*sysclock == *sysclock)
{
continue;
}
/* the clock just ticked */

If sysclock were not volatile-qualified, the compiler would
almost certainly treat this as a forever-loop. Not good! But
because it's volatile-qualified, the compiler can't assume the
value of *sysclock won't change during the evaluation of the
.... snip ...

I am not enamored of your code, volatile or not. With no
constraints on the execution time of the continue statement, I
fear many ticks are going to be missed. I suggest:

whatever t1, t2;
....
while (t2 == (t1 = *sysclock)) t2 = t1;
 
R

Richard Heathfield

CBFalconer said:
With no
constraints on the execution time of the continue statement, I
fear many ticks are going to be missed. I suggest:

whatever t1, t2;
....
while (t2 == (t1 = *sysclock)) t2 = t1;

Thanks for the correction.
 
F

Francois Grieu

Richard Heathfield said:
Imagine, for
example, an embedded system which has a particular 32-bits-wide memory
location containing the time, using 5 bits for the hours, 6 for the
minutes, 6 for the seconds, and - um - 15 for the 32768ths of a second. :)
The only support the implementation provides for the clock is a function
returning its address. Thus:

volatile unsigned long *sysclock = _GetSystemClockAddress();

Now, your code might have something to do which will only take a few
microseconds, but it wants to wait until a tick has just happened, so that
it can do <whatever> without having the clock change under it. It could do
something like this:

while(*sysclock == *sysclock)
{
continue;
}
/* the clock just ticked */

*sysclock could change during the (virtual) continue part
of the loop. It is likely the wait will often be longer
than 1/32768 s. The loop could even be infinite. Use

{
unsigned long t0;
for (t0 = *sysclock; t0==*sysclock; );
}


Francois Grieu
 
C

CBFalconer

Richard said:
Thanks for the correction.

Actually, it was wrong. Try:

while (t2 == (t1 = *sysclock)) continue;
t2 = t1;

and there is still a possible glitch on the first use.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top