Any need for "volatile" when accessing stuff btwn

This forum is reserved for everything you want to talk about. It could be about programming, opinions, open source programs, development in general, or just cool stuff to share!
Post Reply
Virchanza
Experienced Solver
Experienced Solver
Posts: 78
Joined: Sun Jul 19, 2009 6:12 am

Any need for "volatile" when accessing stuff btwn

Post by Virchanza » Mon Jul 27, 2009 12:29 am

Let's say I have a global variable called "monkey":

int monkey;

And let's that I have two different threads that need to access this variable. Of course, I'm gonna create a wxCriticalSection and do p_critical_section_monkey->Enter() before I access it.

My question though is whether I need to define "monkey" as volatile? E.g.:

int volatile monkey;

leiradella
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Sun Sep 07, 2008 9:49 pm
Location: Rio de Janeiro, Brazil

Post by leiradella » Mon Jul 27, 2009 2:46 am

The volatile keyword is used to avoid compilers optimizing reads from the memory where the variable is stored.

For example:

Code: Select all

int g_int;

...

    for (i = 0; i < 100; i++)
        a += g_int;
In this code, g_int will be evaluated only once (i.e. the memory will be read outside the loop.) If you need it to be evaluated every time it's added to a, you have to declare it as volatile.

You shouldn't need to use volatile in your case. Access to shared variables should be surrounded by mutexes because you cannot guarantee that the read/write will be atomic and the value can come up with garbage.

If you use atomic operations, you can probably avoid the use of mutexes to read/write shared variables.

Cheers,

Andre

Virchanza
Experienced Solver
Experienced Solver
Posts: 78
Joined: Sun Jul 19, 2009 6:12 am

Post by Virchanza » Mon Jul 27, 2009 7:00 am

The reason I asked, is that "volatile" is intended to be used in circumstances where the value of a variable may change spontaneously outside the normal flow of a program. Because its value may spontaneously change, the variable's value should never be cached, it should always be read straight from memory.

If you have two threads accessing the same variable, you could say that one thread would observe a spontaneous change in the variable's value.

For example, here's one particular explanation of "volatile" which I found on the MSDN website:

"The volatile keyword is a type qualifier used to declare that an object can be modified in the program by something such as the operating system, the hardware, or a concurrently executing thread."

I had a look through the manual for multithreading in wxWidgets, but couldn't find any mention of the "volatile" keyword.

Are you 100% certain that I'm safe to declare a global variable as non-volatile, and then go on to edit its value in more than one thread? (Of course I'd use a wxCriticalSection before editing or reading the value).

I think the manual for multi-threading should clarify this.

User avatar
doublemax
Moderator
Moderator
Posts: 15846
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Post by doublemax » Mon Jul 27, 2009 9:33 am

i think in your case you need the volatile keyword.

As leiradella pointed out, important is what kind of optimizations the compiler performs. If the compiler creates code that evaluates the content of a variable only once and then re-uses it later in the code, even using a mutex won't help.
I think the manual for multi-threading should clarify this.
this is not a wxWidgets-specific issue.
Use the source, Luke!

leiradella
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Sun Sep 07, 2008 9:49 pm
Location: Rio de Janeiro, Brazil

Post by leiradella » Mon Jul 27, 2009 1:07 pm

doublemax wrote:i think in your case you need the volatile keyword.
But you still need to make sure you read/write the variable only with atomic operations. Take a look at http://msdn.microsoft.com/en-us/library ... 85%29.aspx.

32-bit reads and writes on 32-bit aligned variables are guaranteed to be atomic on x86 because the bus is also 32-bit. The compiler also ensures proper alignment. But if you're going to read/write 64-bit on a 32-bit processor, you have to use one of the intrinsics to ensure atomic operations.

Also, take note that if you're going to, for example, read, increment and write, you'll have to make all three operations atomic. In this case, use a mutex around that code or one of the intrinsics.

Cheers,

Andre

Virchanza
Experienced Solver
Experienced Solver
Posts: 78
Joined: Sun Jul 19, 2009 6:12 am

Post by Virchanza » Mon Jul 27, 2009 3:11 pm

OK I got the answers I needed. It turns out that I don't need volatile. There's a short discussion of it here:

http://groups.google.ie/group/comp.lang ... 929c344d4/

Also regarding the atomic thing with 32-Bit integers, well that's a no-no as well. I can't remember exactly why, but it's something to do with memory barriers or something like that (CPU cache is involved as far as I know).

leiradella
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Sun Sep 07, 2008 9:49 pm
Location: Rio de Janeiro, Brazil

Post by leiradella » Mon Jul 27, 2009 5:12 pm

Virchanza wrote:Also regarding the atomic thing with 32-Bit integers, well that's a no-no as well. I can't remember exactly why, but it's something to do with memory barriers or something like that (CPU cache is involved as far as I know).
Maybe it's an issue with multi-core architectures, I don't know. But then again, the intrinsics should ensure you atomic operations regardless of the specific architecture. Or use mutexes.

Cheers,

Andre

Post Reply