We have a variable 'int xval' that is being
modified
I notice I have mixed up (switched) x and xval in my previous reply...
extern int xval;
void f(void)
{
int a, b, c, ... x, y, z;
x = xval;
// lots of code using a ... z;
}
Well, if you are content with any old possible value of xval (i.e. you
have no synchronization on it anywhere), you are right; but then you
might as well make xval a constant -- just use the first value it ever
had. You have no guarantees that the thread calling f() will EVER have
its hardware cache synchronized to whoever is producing xval. Cache
coherency again...
Otherwise, I bet you *do* have some synchronization, somewhere, for
xval in the thread that calls f. Wherever that place is, save the
cached value, i.e.
mutex_lock()
x = xval
mutex_unlock()
f (x)
... and now there is no need for volatile, data flow becomes clear etc.
So you are right, the way you have structured your short snippet of
code you might be preventing an optimization -- but there is still too
little context, and I bet structuring the code differently will
obviate the need for volatile, plus provide predictable data flow.
A. If xval is being modified by an interrupt handler
then clearly you can't use the mutex - you can't risk
to block the interrupt handler.
Let's say a signal handler, not an interrupt handler. Let's stick with
userspace (C89 + Posix) -- kernels have different rules, different
primitives etc.
*there is no difference* between xval being modified
by
an interrupt handler, or by another thread. The difference
There is a difference. A signal will modify x immediately. A different
thread running on a different cache might never propagate the update
the to hardware cache used by f()'s thread.
A few more things, for the sake of completeness:
In the signal case, you should of course make sure the signal is
caught by the thread who reads x, by using pthread_sigmask()
appropriately. Or make the program non-threaded. Otherwise, you now
have two problems...
Also, strictly speaking if you're using a sighandler plus volatile,
you should also declare xval as sig_atomic_t.
-- Dan