volatile

Chris Torek chris at mimsy.UUCP
Thu Apr 14 02:42:56 AEST 1988


>>      extern volatile int user_interrupt;
>>      while (!user_interrupt)
>> 	 sleep(1);

In article <49255 at sun.uucp> limes at sun.uucp (Greg Limes) writes:
>Please do not misunderstand me, I would like to see "volatile"
>added -- but why would it be required above? If "user_interrupt"
>is an external variable, then the compiler is not free to assume
>that it will not change across a function call.

The compiler *is* free to make that assumption if it examines the
function and finds that it does not write into user_interrupt.
For instance, if `sleep' is implemented as (say)

	typedef unsigned long u_long;
	sleep(unsigned n) {
		static volatile u_long *const timerp = (u_long *)0xfc000040;
		register u_long expect = *timerp + n;
		while (*timerp < expect) /*void*/;
	}

and the code for sleep is stored in some format that the
compiler can read, then the compiler can see that sleep cannot
change user_interrupt.

The main problem with volatile is that it does not have well-
defined semantics.  It *cannot* have well-defined semantics.
Consider a load/store architecture versus a Vax-like architecture.
If I write

	volatile char c;
	...
	c++;

the load/store machine must generate something like

	movbl	_c,r212
	addl	#1,r212
	movlb	r212,_c

which is one read and one write; the Vax-like machine just runs

	incb	_c

which is one read/modify/write.

The reason volatile exists is because it is a machine-independent
means of specifying something that is inherently machine-dependent
but which affects every implementation that does what might be
called `nonobvious optimisation'.  Like the size of `pointer_t'
(void *) or the length of `size_t', volatile is a machine- and
compiler-dependent construct that can be used to give machine-
and compiler-independent results:

	#include <atomic.h>

	semaphore_t sem;

	...
		SEM_LOCK(&sem);
		...
		SEM_UNLOCK(&sem);

where <atomic.h> might say

	typedef volatile int semaphore_t;
	#define SEM_LOCK(semp) while ((*semp)++) --*(semp)
	#define SEM_UNLOCK(semp) --*(semp)

or it might say instead

	typedef volatile short semaphore_t;
	#define SEM_LOCK(semp) \
		while (_builtin_test_and_set(semp)) \
			_builtin_atomic_clear(semp)
	#define SEM_UNLOCK(semp) _builtin_atomic_clear(semp)

or any of a number of other possibilities.

What `volatile' DOES is machine-dependent.  What `volatile'
EXPRESSES (`hands off! this is a weird object!') is not, or
not entirely.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at mimsy.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.lang.c mailing list