Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java's volatile in C?

I'm aware of the use of volatile in Java. That is (based on the wikipedia article):

There is a global ordering on the reads and writes to a volatile variable. This implies that every thread accessing a volatile field will read its current value before continuing, instead of (potentially) using a cached value.

I also I'm aware that there exists the volatile keyword in C but in a quite different context, mainly to be used in memory-mapped I/O.

So I was wondering, is there some construct like Java's volatile in C? Which will prevent reading cached values of a variable?

If it doesn't exist in C, is there perhaps a library with such a construct, like pthread?

like image 846
Fooko R. Avatar asked Feb 10 '12 17:02

Fooko R.


2 Answers

volatile in C is basically an anachronism that was intended for a completely different scenario and is NOT useful for multi threaded programming. For some reasons or another even the newest c++ standard couldn't give it more meaning but had to invent a new keyword instead.

Mind you this means volatile as defined by the C standard is useless, compilers may give you additional guarantees (I know that MS VC does and I think it gives basically the same guarantees as does volatile in java) but that means the program is locked to that one compiler. Most compilers also have some intrinsics to insert memory barriers, which is a bit more explicit but again not portable per se.

In practice you're probably best of using some higher level threading library that offers the right tools for the job. E.g. POSIX gives you low level memory barriers afaik.

On the c++ site it's better since 0x11 - the standard does offer std::atomic_thread_fence and atomic variables. Note though that the c++0x11 memory model is NOT identical to the java one, so you'll have to be careful when porting.

like image 93
Voo Avatar answered Sep 28 '22 02:09

Voo


The behavior of volatile isn't necessarily different; it's the platform and context that is different. You specifically mentioned memory-mapped devices in your question. If you have a memory mapped device like some piece of hardware that can flip a register that is represented by a variable in your code, then obviously you want a way to indicate that. If you don't, then the compiler will always work under the assumption that the only system that can change your code is your program and might optimize it out.

A good example would be if you are using a variable in a decision or control flow situation. If this variable is never manipulated in your code directly but could be flipped by a signal or some memory-mapped hardware, the compiler might optimize the decision condition in to a boolean value since it will assume the value won't change. So when the hardware flips the value, it doesn't reflect in the running code because of the compiler optimizations.

Java "caches" are basically the same behavior. Your disconnect seems to be coming from the fact that you aren't making the mental bridge between C being compiled code and Java being JIT compiled byte code running inside of a virtual machine. Java inherits its volatile behavior from C but the consequences of this behavior are drastically different because of the runtime context.

like image 28
Doug Stephen Avatar answered Sep 28 '22 02:09

Doug Stephen