Re: mutex question



David Jones wrote:
Stealer wrote:

// ???? while(x); <> while(x) { statements} ???
// VC Compiler bug in Release configuration

[...snip...]

continue_flag = 1;
CreateThread(NULL, 0, ThreadProc, 0, 0, 0);
while (continue_flag)
{
//printf("You : I love you, Bill\n"); // you can not exit this program
if remove this line.
};

[...snip...]

// Note: You must buid in Release to find out the problem
// Disassembly:
// 00401048 jmp 00401048
// --> no compare before jmp


This is not a compiler bug -- this is a code bug. The continue_flag
variable should be declared as volatile since it can be modified by
another thread. Since you're not changing continue_flag in the loop,
it is perfectly valid for the compiler to optimize the check away
completely.

That's true.

This is why the 'volatile' keyword exists -- to tell the compiler
that a variable can change unexpectedly, such as when it is shared
between threads. Today's compilers are smart, but they can't read
your mind (yet). :)

That is *not* what volatile is for - multithreading is not part of its utility, rather hardware interaction is.

Why does it not optimize the check away when a call to printf is in
the loop? Maybe since it's a global variable and you're calling a
function in another compilation unit, it thinks that the variable
might be extern'ed and potentially modified by that function. I'd
bet that if you replaced the statement with, say, setting the value
of a local variable, you'd get the optimized code -- just jmp. (It
would probably move the assignment out of the loop.)

Long story short: use 'volatile' on variables shared between threads.

On the contrary, it is *not* necessary nor is it sufficient to use volatile on variables shared between threads. Instead, use the Interlocked* operations, the new memory barrier calls and the synchronization primitives. Volatile doesn't cause cache synchronization between CPUs, so it is possible for two apparently simultaneous reads by different CPUs to get different values (though this doesn't apply to x86 multiprocessor, only to Itanium and PowerPC AFAIK). Memory barriers (and the operations that emit them, such as EnterCriticalSection, WaitForSingleObject and InterlockedCompareExchange), not volatile, are the correct mechanism to force updating of variables between threads. If you use memory barriers, volatile doesn't help, and if you don't use memory barriers, volatile won't work on all platforms, so it is neither necessary nor sufficient to use it.

There's a paper on it here:
http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf

Alternatively, google groups will have lots of posts about this.

Tom
.



Relevant Pages

  • Re: MSDN volatile sample
    ... must be specified to get the memory barriers. ... Telling us we have to put volatile keyword to thread sharing data ... Now I strongly suspect whether compiler will generate any wrong code -- ... It seems that volatile will make wrong optimization to prevent thread1 ...
    (microsoft.public.vc.language)
  • Re: Efficient way to synchronize bool variables
    ...  volatile, even with memory barriers, does NOT create ... thread-safe modifications, and will not work. ... Couple that with volatile ... THe compiler is horribly conservative ...
    (microsoft.public.vc.mfc)
  • Re: Share .cpp and .h along projects
    ... larger object can be controlled in a threadsafe manner using a volatile ... pointer and memory barriers. ... The compiler DOES apply those optimizations. ...
    (microsoft.public.vc.language)
  • Re: Disabling interrupts to protect data
    ... understand about interrupt disabling (and the related topic of volatile ... assembly functions specifically include memory barriers, ... probably see the cliand stias volatile accesses (depending on the ... compiler and the definition of these macros). ...
    (comp.arch.embedded)
  • Re: Visual C++ 6.0 Compiler Problem with Optimizations Switched On
    ... Ulrich Eckhardt wrote: ... > compiler bug. ... Just adding 'volatile' might work with this compiler ...
    (microsoft.public.vc.language)

Loading