Ok, first of all, it is broken. You're just lucky your compiler created code that, by accident, seems to work (or maybe unlucky, because it could hide subtle bugs in corner cases).
I found that whenever the variable is updated at callback, its automatically updated in the thread without declaring the variable as a volatile. well, I am not clear how it is managed.
Starting from here: It is one and the same variable. Threads share the same address space. So, this is what you would naively expect.
volatile
is about optimizations. A C compiler is free to do a lot of modifications to your code in order to make it faster, this includes reordering of statements, not reading an accessed variable because the same value is in a register, even "unrolling" loops and a lot more. Normally, the only restriction is that the observable behavior stays the same (google for it, I don't want to write a book here.)
Reading a variable from normal memory does not create any side effects, so it can be legally left out without changing behavior. C (prior to c11) does not know about threads. If a variable was not written to in some part of code, it is assumed to hold the same value as before.
Now, what volatile
gives you is telling the compiler this is not normal memory but a location that could change outside of the control of your program (like e.g. a memory mapped I/O register). With volatile
, the compiler is obliged to actually fetch the variable for any read operation and to actually store it for any write operation. It's also not allowed to reorder accesses between several volatile
variables. But that's all and it is not enough for synchronizing threads. For that, you also need the guarantee that no other memory accesses or code execution is reordered around accesses of your variable, even with multi-processors -> you need a memory barrier.
Note this is different from e.g. java where volatile
gives you what you need for thread synchronization. In c, use what the pthreads
library gives you: mutexes, semaphores and condition variables.
tl;dr
Your code works correctly by accident. In c, volatile
for threads is wrong (and unnecessary), use synchronization primitives as provided by pthreads
.