volatile

J

Jason Curl

I was reading a previous article about when to use volatiles.

My program has a shared memory buffer that is being accessed by two
threads. The threads are protected by an operating system specific means
(Windows Mutexes) so that I write using one thread and read using
another thread with it impossible to read and write at the same time.

So I read information from an external device using a thread (the time
it takes to do the read is dependent on that device and may be from
200ms to 30 seconds), while the other thread simply copies the
information into another buffer once per second and then operates on the
copy.

Now, the C question: is this portable if I write with one thread, and
only read "once" into a local variable in the other thread without
defining these buffers as being volatile?

I ask this so then the compiler may optimise some of the work it is doing.
 
F

Flash Gordon

On Wed, 06 Oct 2004 17:20:02 +0200

Now, the C question: is this portable if I write with one thread, and
only read "once" into a local variable in the other thread without
defining these buffers as being volatile?

I ask this so then the compiler may optimise some of the work it is
doing.

You still need to declare the shared buffers as volatile but you don't
need to declare the local variables as volatile. Otherwise the compiler
is free to spot that you don't read the value you wrote and not bother
writing it. The mutexes solve a different problem which is off topic
here, they prevent you getting half updated data.
 
M

Minti

Jason Curl said:
I was reading a previous article about when to use volatiles.


Sorry I did not read that one.

My program has a shared memory buffer that is being accessed by two
threads. The threads are protected by an operating system specific means
(Windows Mutexes) so that I write using one thread and read using
another thread with it impossible to read and write at the same time.

So I read information from an external device using a thread (the time
it takes to do the read is dependent on that device and may be from
200ms to 30 seconds), while the other thread simply copies the
information into another buffer once per second and then operates on the
copy.

Now, the C question: is this portable if I write with one thread, and
only read "once" into a local variable in the other thread without
defining these buffers as being volatile?

Well strictly speaking you would need to consult your Compilers reference
manual and read specifically read about how it deals with mutexs. It is
posssible that whenever a mutex is acquired, the data would be read afresh
rather than using a thread level cache. Java does it this way. Not sure
about Windows.
 
J

Jason Curl

Flash said:
On Wed, 06 Oct 2004 17:20:02 +0200




You still need to declare the shared buffers as volatile but you don't
need to declare the local variables as volatile. Otherwise the compiler
is free to spot that you don't read the value you wrote and not bother
writing it. The mutexes solve a different problem which is off topic
here, they prevent you getting half updated data.
I came across another problem. Marking the particular entries gives me
(obviously enough) warnings for functions like 'memcpy'.

Is it specified in the standard C levels of optimisation? e.g. if I use
a compiler specific pragma to turn off optimisation for some special
functions so they'll be effectively treated as volatile?

Otherwise, I'm guessing a lot of work to change function signatures to
"volatile" (my goal is to reduce the number of real warnings to zero).

On a similar topic, when you pass a 'char *' to a function that accepts
a 'const char *' this is ok. Is it also OK to pass a 'char *' to a
function that accepts 'volatile char *'?

Is this even the right declaration to use to declared a shared memory
buffer? e.g. 'volate char *' and not 'char * volatile'?

Thanks for your input,
Jason.
 
D

Dan Pop

In said:
On Wed, 06 Oct 2004 17:20:02 +0200



You still need to declare the shared buffers as volatile but you don't
need to declare the local variables as volatile. Otherwise the compiler
is free to spot that you don't read the value you wrote and not bother
writing it. The mutexes solve a different problem which is off topic
here, they prevent you getting half updated data.

The mutexes solve whatever problem(s) the implementor decides to. For
example, POSIX mutexes also guarantee data syncronisation between threads,
making volatile useless.

Dan
 
M

Minti

Dan Pop said:
In <[email protected]> Flash Gordon

The mutexes solve whatever problem(s) the implementor decides to. For
example, POSIX mutexes also guarantee data syncronisation between threads,
making volatile useless.

<OT>
Just out of curiosity, any implementations or standards that implement
mutexes otherway.
</OT>
 
E

Eric Sosman

Minti said:
<OT>
Just out of curiosity, any implementations or standards that implement
mutexes otherway.
</OT>

comp.programming.threads is thataway ---+---+---+--->
| | |
| | +--->
| |
<---+ |
|
V
 
C

Chris Torek

I came across another problem. Marking the particular entries gives me
(obviously enough) warnings for functions like 'memcpy'.

Is it specified in the standard C levels of optimisation? ...

I am not sure what "it" is here, but the C standard does not say
much at all about optimization. It gives you a blunt instrument
for disabling it -- the "volatile" keyword -- but does not, and
really cannot, specify all the details. In other words, "volatile"
is typically necessary, but not by itself sufficient, for dealing
with hardware, multithreading, and the like.
On a similar topic, when you pass a 'char *' to a function that accepts
a 'const char *' this is ok. Is it also OK to pass a 'char *' to a
function that accepts 'volatile char *'?
Yes.

Is this even the right declaration to use to declared a shared memory
buffer? e.g. 'volate char *' and not 'char * volatile'?

"volatile char *p" means that p points to "volatile char"s, i.e.,
chars that work or change in ways not modeled by "ordinary RAM".
(The values stored there may change without warning, or the act of
loading or storing values there may cause hardware to react, etc.,
none of which is true for "ordinary" memory.)

"char *volatile p" means that p itself is volatile, but points to
ordinary RAM. Thus, reading the value in p, or writing a new
value to p, is not modeled as a regular memory operation, but
once you have the value read from p, reading or writing *<that> is
accessing ordinary memory.

"volatile char *volatile p" means that p, and the memory to which
*p points after reading p, are both volatile ("non-ordinary").
 

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

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,227
Latest member
Daniella65

Latest Threads

Top