[net.lang.c] C and real hardware

dan (04/27/83)

	In C code such as device drivers, one often encounters code like:

	while (ADDR->c_reg&BUSY)
		;

	where one is testing bits of a hardware device register, and waiting
for a change.

	In there anything in the C specification which would prevent a good
(but obviously not perfect) optimizer from reading the value of the device
register just once, stuffing it into a CPU general purpose register and looping
on its value ?
	I have noticed that at least some of the 4xbsd makefiles seem to
purposely avoid the optimizer - is this sort of thing the reason ?
	Might not C benefit from some additional type (e.g. "unregister")
which would tell an optimizer what was up. I believe DEC's MicroPower Pascal has
a type called "volatile" which prevents this sort of thing.

					Dan Ts'o

tom (04/28/83)

RE: possible undesired optimization of code like:

	while (ADDR->c_reg&BUSY)
		;

I have worked with drivers a great deal in older versions of UNIX and
never had a problem with optimization eliminating the repeated memory
reference.  One reason may be that since UNIX is a timesharing system,
there are very few actual "busy waits" as above (a neat way to hang
a system) but instead:

	while (ADDR->c_reg&BUSY)
		sleep((caddr_t)&x, PRIBIO);

The subroutine call in the loop is enough to turn off any optimization.

But otherwise, in the first example it would seem reasonable to optimize
out the memory reference, to the programmer's displeasure.  This could
become a more widespread problem when shared data spaces cause user
programs to use the same type of code. The "unregister" or "volatile"
declaration mentioned could prove useful (I prefer the second term).

Tom Beres
{we13, mcnc, seismo}!rlgvax!tom

henry (04/29/83)

The old BLISS-11 compiler had an elaborate set of constructs for telling
the compiler what could and could not be safely assumed for purposes of
optimization.  For example, I think there was a way you could convince
it not to optimize a wait-on-device-register-bit loop into one register
access and an infinite loop.  It's rather unfortunate that C compilers
generally have not attempted enough optimization to run into these
problems.  Just how one solves them cleanly in C is not obvious.

					Henry Spencer
					U of Toronto

bstempleton (05/02/83)

Clearly "Unregister" is not the right name for this kind of type.
In general, you are correct in a need for this type.  Not just for
memory-mapped i/o devices, but also for any machine with multiple
processes sharing memory.   Perhaps the atribute "Shared" is good for
in a way you can consider a memory-mapped i/o location to be shared between
the processor and the device.

mjs (05/02/83)

Hey folks, any compiler which "hyperoptimizes" the memory reference out
of the statement

	while (strptr->smember & CONST)
		;

is not a C compiler.  The semantics of that statement are that the
expression is evaluated until it is not true.  Evaluation of the
expression implies evaluating "strptr->smember".  This must be done for
every iteration of the loop.  If your compiler doesn't evaluate the
structure reference every time through the loop, it just ain't a C
compiler!

		Martin Shannon, Jr.
Phone:		(201) 582-3199
Internet:	mjs@mhb5b.uucp
UUCP:		{allegra,rabbit,alice,mhb5b,mhb5c}!mjs

arvind@ubvax.UUCP (06/25/83)

#R:rlgvax:-34500:ubvax:4100001:000:981
ubvax!arvind    Apr 29 19:10:00 1983

***** ubvax:net.lang.c / rlgvax!tom /  4:40 pm  Apr 28, 1983
RE: possible undesired optimization of code like:

	while (ADDR->c_reg&BUSY)
		;

I have worked with drivers a great deal in older versions of UNIX and
never had a problem with optimization eliminating the repeated memory
reference.  One reason may be that since UNIX is a timesharing system,
there are very few actual "busy waits" as above (a neat way to hang
a system) but instead:

	while (ADDR->c_reg&BUSY)
		sleep((caddr_t)&x, PRIBIO);

The subroutine call in the loop is enough to turn off any optimization.

But otherwise, in the first example it would seem reasonable to optimize
out the memory reference, to the programmer's displeasure.  This could
become a more widespread problem when shared data spaces cause user
programs to use the same type of code. The "unregister" or "volatile"
declaration mentioned could prove useful (I prefer the second term).

Tom Beres
{we13, mcnc, seismo}!rlgvax!tom
----------

arvind@ubvax.UUCP (06/25/83)

#R:rlgvax:-34500:ubvax:4100002:000:380
ubvax!arvind    Apr 30 11:15:00 1983

***** ubvax:net.lang.c / arvind /  7:10 pm  Apr 29, 1983
***** ubvax:net.lang.c / rlgvax!tom /  4:40 pm  Apr 28, 1983
RE: possible undesired optimization of code like:

	while (ADDR->c_reg&BUSY)
		;

"shared" in place of "volatile" or "unregister" may be a nicer attribute
for vaibales "shared" between processes; the latter includes external
device processes in case of drivers.