[comp.lang.c] volatile isn't necessary, but it's there

dmr@alice.UUCP (04/06/88)

Since a good many messages have ardently defended the 'volatile'
type qualfier, it might be worth pointing out a few things.

Most important, the notion is not, so far as I know, under serious attack
in X3J11; there is every reason to believe it will be in ANSI C.
In my noalias diatribe I took a passing swipe at it (a position
I will defend below), but on the whole, I am willing to leave volatile
alone and concentrate on getting rid of noalias.

Volatile is of use only with optimizing compilers; those that don't
do some kind of data-flow analysis can ignore it.  More bluntly,
it is intended to be used in cases where your compiler will do something
other than what your program plainly asks it to do.  People seem to be
thinking of three categories of use.

1)  Accessing memory-mapped device registers

2)  Special cases involving automatic variables in a routine
    that calls setjmp

3)  Shared memory, and also interrupt routines.

The X3J11 documents (the dpANS itself and the Rationale) specifically
mention the first two, but carefully avoid talking about the third.

I have no real gripe about the first; I just think it is unnecessary.
It seems just as reasonable for purveyors of optimizing compilers for machines
with memory-mapped IO to have a compiler flag that says "please
be cautious about cacheing things in this routine."
Alternatively, they could accept a #pragma in the code.
It is true that putting volatile in the language encourages
everyone to do the job in the same way, but it is by no means
clear that, on balance, `volatile' makes C a better language.

There is a real cost in having the feature in the language.
It is just one more peculiar thing to learn and be confused
about.  If there is one thing I have learned from reading this
newsgroup, and other popular reactions to C, it is that people
have trouble understanding the language.  Features that do nothing
but request a compiler not to compile your program incorrectly
are not really what C needs.

(I'm especially amused by some of the more extreme positions
stated in favor of `volatile.'  May I be permitted to assert
that it is possible to write a successful operating system
without `volatile,' even on machines with memory-mapped IO?)

I am much more worried about the second justification.  It simply
caters to broken compilers.  Because some machines find it
hard to handle setjmp/longjmp properly, X3J11 ruled that "[following
a longjmp], [a]ll accessible objects have values as of the time
longjmp was called, except that the values of objects of automatic storage
duration that do not have volatile type and have been changed between
the setjmp invocation and longjmp call are indeterminate."
The Rationale is fairly explicit about the apologia.
This is just a botch; the committee should have insisted
that, if necessary, the compiler recognize setjmp and handle its caller
specially.  They edged around this anyway; what other use
is the insistence that setjmp be a macro?  (A footnote in the
Rationale poses this question, too.)

The third hope for volatile, namely shared memory, is in some ways the
most interesting because it nibbles at the edge of mechanisms
that will become more important in the future.  Nevertheless,
as several have pointed out, the Standard conspicuously avoids
the extensions needed to make shared memory work
(e.g. semaphores).  The dpANS even says, "what constitutes
an access to an object that has volatile-qualified type is
implementation-defined," and the sections that discuss
what volatile actually does mean are correspondingly inexplicit.
If you hope to find in the Standard that "extern volatile mutex; ++mutex"
has an iron-clad meaning, you'll be disappointed.
Thus, using volatile for shared memory may be syntactically
portable, but it is not semantically portable, because it
has no defined semantics.

To summarize, using volatile for device registers is plausible;
using it for longjmp is a rank copout; using it for shared memory
is premature.

Has anyone else noticed that a lot of the more peculiar things that X3J11
has added (volatile, and especially noalias) are there for the
benefit of compiler writers and benchmarkers, and not for the user?
(I know how it happens, though; after all, I invented 'register.')

		Dennis Ritchie
		research!dmr
		dmr@research.att.com

eric@snark.UUCP (Eric S. Raymond) (04/07/88)

In article <7794@alice.UUCP>, dmr@alice.UUCP writes:
>It seems just as reasonable for purveyors of optimizing compilers for machines
>with memory-mapped IO to have a compiler flag that says "please
>be cautious about cacheing things in this routine."

I see your point, but I think the alternative you're proposing is ugly,
because it creates a kind of constraint on module organization that wasn't
there before and has nothing to do with what module structure ought to be
about (clean interfaces and data hiding).

>Alternatively, they could accept a #pragma in the code.

This is the alternative I'd favor. I think X3J11 should have a class of
'required' pragmas to do such optimization hinting.

>There is a real cost in having the feature in the language.

While I agree with your keep-it-simple philosophy in general, I think I
disagree with your implication here. I don't think C is a language for
novices; the issue, to me, is whether volatile complicates C to the
point where a skilled, multi-language programmer can no longer hold
the entire C language model in his head. I don't think volatile does
that, though it skates close.

(Note that I'm not insisting that all languages, or even all C-like
languages, should be small in this sense -- as an abstract-data-type-design
enthusiast I'm itching to get my hands on C++, which has *certainly* passed
that limit. But smallness in this sense is one of C's major strengths and
ought to be preserved by anything claiming to be a C standard)

>(I'm especially amused by some of the more extreme positions
>stated in favor of `volatile.'  May I be permitted to assert
>that it is possible to write a successful operating system
>without `volatile,' even on machines with memory-mapped IO?)

FWOOOM! *Someone* just got very politely flamed off above the ankles. :-) :-)
I succumbed to helpless giggles for a few minutes after first reading this...

>This is just a botch; the committee should have insisted
>that, if necessary, the compiler recognize setjmp and handle its caller
>specially.

O.K., I can sure agree with this. Is there any hope volatile can be
strengthened this way? At least maybe we should push correct longjmp
behavior as a named common extension and recommended behavior, so that
compiler implementers are put on notice that it is the Right Thing.

>The third hope for volatile, namely shared memory, is in some ways the
>most interesting because it nibbles at the edge of mechanisms
>that will become more important in the future.  Nevertheless,
>as several have pointed out, the Standard conspicuously avoids
>the extensions needed to make shared memory work
>(e.g. semaphores).

Well...yes. Semaphore implementation is sufficiently hardware-dependent
that they really have to be considered outside the purview of a language
definition (after all, if you don't have an atomic test-and-set instruction
at some level, you lose).

I'm afraid I don't see how this connects with the ill-definedness of volatile
on shared memory. After all, if increment to a memory location is atomic,
'volatile murex; murex++' has semantics that are meaningful and useful without
giving you the strict atomic-test guarantee that full semaphores would.

>Has anyone else noticed that a lot of the more peculiar things that X3J11
>has added (volatile, and especially noalias) are there for the
>benefit of compiler writers and benchmarkers, and not for the user?

Yeah. Maybe we should form our own analogue of Vietnam Veterans Against The
War; Compiler Hacks Against Compiler-hack Elitism.
-- 
      Eric S. Raymond                     (the mad mastermind of TMN-Netnews)
      UUCP: {{uunet,rutgers,ihnp4}!cbmvax,rutgers!vu-vlsi}!snark!eric
      Post: 22 South Warren Avenue, Malvern, PA 19355   Phone: (215)-296-5718

gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/07/88)

In article <7794@alice.UUCP> dmr@alice.UUCP writes:
>Has anyone else noticed that a lot of the more peculiar things that X3J11
>has added (volatile, and especially noalias) are there for the
>benefit of compiler writers and benchmarkers, and not for the user?

As I suspect Dennis knows, by far the majority of the X3J11 committee
are C implementors or at least represent the interests of C implementors.
The "user advocates" sometimes have an uphill battle, especially on
issues that are perceived as affecting the marketability of C compilers.
A C vendor quite naturally wants to be able to claim that its compiler
results in faster benchmark times than the competition's.  Thus, the
implementor representatives tend to favor features that allow a high
degree of optimization.  The MS-DOS C market in particular appears to be
highly competitive along these lines.

I don't really know a way to counter this inevitable trend other than to
show up at the meetings and try to represent a user's viewpoint.

karl@haddock.ISC.COM (Karl Heuer) (04/08/88)

In article <7794@alice.UUCP> dmr@alice.UUCP writes:
>[The |volatile| clause for setjmp] simply caters to broken compilers....
>This is just a botch; the committee should have insisted that, if necessary,
>the compiler recognize setjmp and handle its caller specially.

This is true.  If I have time to write it up before the deadline, I'll propose
that this clause be deprecated.  (I presume there are vendors that would
object if it were simply removed.)

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

guy@gorodish.Sun.COM (Guy Harris) (04/08/88)

> The third hope for volatile, namely shared memory, is in some ways the
> most interesting because it nibbles at the edge of mechanisms
> that will become more important in the future.  Nevertheless,
> as several have pointed out, the Standard conspicuously avoids
> the extensions needed to make shared memory work
> (e.g. semaphores).  The dpANS even says, "what constitutes
> an access to an object that has volatile-qualified type is
> implementation-defined," and the sections that discuss
> what volatile actually does mean are correspondingly inexplicit.
> If you hope to find in the Standard that "extern volatile mutex; ++mutex"
> has an iron-clad meaning, you'll be disappointed.

It is worth noting, for example, that there is no guarantee that "++mutex" is
an atomic operation.  It is, in fact, worth noting that even if "extern
volatile char mutex;" was used, there would be no guarantee that "++mutex" is
atomic.  In all cases, for example, "++mutex" takes an instruction to load
"mutex" into a register, an instruction to increment it, and an instruction to
store it, on a SPARC.  The same would be true of any other architecture lacking
an instruction performing an "add 1 to memory" operation.

This is a real problem; there were some mildly entertaining bugs on Sun-4
caused by statements such as "++mutex;" in the kernel not being surrounded by
"spl" calls.

lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) (04/08/88)

In article <7794@alice.UUCP>, dmr@alice.UUCP writes:
	... notes on volatile ...

> Has anyone else noticed that a lot of the more peculiar things that X3J11
> has added (volatile, and especially noalias) are there for the
> benefit of compiler writers and benchmarkers, and not for the user?
> (I know how it happens, though; after all, I invented 'register.')

Yes.  I was shocked when I read that abs() was taken out of <math.h> and
more so when I read the reason.  abs() was removed from <math.h> because
some compilers will create executable images with unused floating point
routines in them <math.h> is included.

Flame on: Of all the stupid things I read in the draft this takes the
cake.  Why don't the vendors fix their stupid compilers and leave the
<math.h> users alone!  Come on!  abs() is a math function and <math.h>
is where it belongs!
Flame off:

Seriously, this is a minor botch but still a botch.  I'm going to
write to complain about this (among other things) in particular
and the "vendor bias" in general.

Future language standardizations should have more representation by
users, and this should be required by ANSI.  We've been had one too
many times.

-- 
Larry Cipriani, AT&T Network Systems and Ohio State University
Domain: lvc@tut.cis.ohio-state.edu
Path: ...!cbosgd!osu-cis!tut.cis.ohio-state.edu!lvc (weird but right)

barmar@think.COM (Barry Margolin) (04/08/88)

In article <7624@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>In article <7794@alice.UUCP> dmr@alice.UUCP writes:
>>Has anyone else noticed that a lot of the more peculiar things that X3J11
>>has added (volatile, and especially noalias) are there for the
>>benefit of compiler writers and benchmarkers, and not for the user?
>I don't really know a way to counter this inevitable trend other than to
>show up at the meetings and try to represent a user's viewpoint.

Who says that users aren't interested in good optimization?  I recall
that several of the advocates of volatile in this forum were from the
user community.  They are looking forward to compilers that can do a
good job of optimization without screwing them because of it.

Making things a little easier for the compiler writers means that they
can include more good features.  And that directly benefits the users.

Barry Margolin
Thinking Machines Corp.

barmar@think.com
uunet!think!barmar

gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/08/88)

In article <19158@think.UUCP> barmar@fafnir.think.com.UUCP (Barry Margolin) writes:
>Who says that users aren't interested in good optimization?  I recall
>that several of the advocates of volatile in this forum were from the
>user community.  They are looking forward to compilers that can do a
>good job of optimization without screwing them because of it.

It's a matter of keeping one's priorities straight.
It is much more important that an algorithm produce
the correct results than that it be maximally fast
on a particular piece of hardware.  The way this is
supposed to be achieved in C programming is for the
compiler to correctly map the abstract virtual 
machine semantics onto the hardware and for the
programmer to provide a correct recipe for the
virtual machine.  This task is made much harder if
the virtual machine semantics are complicated, for
example to support "noalias" virtual "handles" and
so forth.

When I need more speed, I normally need a LOT more
speed, so I switch to a different machine.  Small
gains from improved optimizer technology at the
expense of code reliability are not helpful.

mangoe@mimsy.UUCP (Charley Wingate) (04/09/88)

>Volatile is of use only with optimizing compilers; those that don't
>do some kind of data-flow analysis can ignore it.  More bluntly,
>it is intended to be used in cases where your compiler will do something
>other than what your program plainly asks it to do.

These statements only acquire truth because the default understanding of
what the compiler ought to do is very very conservative and tends to reflect
the most simple-minded way of understanding the code.

Without volatile, and allowing ...

>that it is possible to write a successful operating system
>without `volatile,' even on machines with memory-mapped IO

.... it is pretty difficult to formally specify what any action on an
non-local variable does, unless you essentially *know* whether the non-local
object is "volatile" or not.  If you're going to allow optimization on
non-local references, therefore, that information about volatility has to be
given to the compiler somehow.

This essentially establishes "volatile" as a semantic element, because its
effect is to "turn off" the semantic rules that optimizers rely upon.  As a
semantic component, it belongs in the language standard itself, not as a bag
on the side.

It appears that what people do now is, in effect, supply the volatility
information through compiler flags.  This, I feel, is undesirable because it
stores semantic information outside the code itself; without it, there is
nothing in the code to tell you that compiler options will change the
behavior of the program.  Some "volatile" construct IS necessary.

I'm not entirely convinced of the "confusion" argument either.  For one
thing, a person who can't understand the semantic implications of "volatile"
probably shouldn't be licensed to write the kind of programs that require it
in the first place!  :-) But more to the point, the only time it should
matter whether "volatile" is used is where it is actually necessary; if it
is used where it is unnecessary, the actual result had better be unaffected.
Perhaps a lot of people do not understand this implication, but I would
claim that this reflects the generally poor understanding of language
semantics in the profession.  People are able to just sit down and write
BASIC and FORTRAN programs without formal training largely because the
programs they write don't test the semantics of the language very far; the
time has to come, though, when language designers ought to be able to expect
something beyond a first-grade understanding of programming languages--
especially when we're talking about a language which is routinely used for
systems and multiprocess programming.

C. Wingate

oz@yunexus.UUCP (Ozan Yigit) (04/09/88)

Eric S. Raymond (snark!eric) writes
>
>Yeah. Maybe we should form our own analogue of Vietnam Veterans Against The
>War; Compiler Hacks Against Compiler-hack Elitism.
>
	I think, seriously, something needs to be done, and soon.
	More than once, the *commercial incentives* behind this
	standard has been commented upon. Needless to say, the
	resulting *standard* bogosity will be cemented by the
	commercial implementations of the language. My hope is
	something like the Gnu C compiler may help the cause: It is
	an excellent compiler, for free, and currently free from the
	*standard*. [Sounds familiar: Common(?) Lisp vs. Scheme,
	and Franz, and ...]

	Of course, it also helps the New Testament (K&R^2) came out
	just in time...
-- 
... and they will all		Usenet: [decvax|ihnp4]!utzoo!yunexus!oz
bite the dust ... 	    		......!seismo!mnetor!yunexus!oz
	comprehensively. ...	Bitnet: oz@[yusol|yulibra|yuyetti]
Archbishop Tutu			Phonet: +1 416 736-5257 x 3976

meissner@xyzzy.UUCP (Michael Meissner) (04/09/88)

In article <10068@tut.cis.ohio-state.edu> lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) writes:
| Seriously, this is a minor botch but still a botch.  I'm going to
| write to complain about this (among other things) in particular
| and the "vendor bias" in general.
| 
| Future language standardizations should have more representation by
| users, and this should be required by ANSI.  We've been had one too
| many times.

Then where were you?  Seriously, yes the ANSI C committee is top heavy
with implementors, but very few users have ever come to the meetings.
We do have a few users (around 8 out of 45ish voting members).  In fact,
one of the "users" spent his own money to attend.
-- 
Michael Meissner, Data General.		Uucp: ...!mcnc!rti!xyzzy!meissner
					Arpa/Csnet:  meissner@dg-rtp.DG.COM

gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/10/88)

In article <10988@mimsy.UUCP> mangoe@mimsy.umd.edu.UUCP (Charley Wingate) writes:
>>Volatile is of use only with optimizing compilers; those that don't
>>do some kind of data-flow analysis can ignore it.  More bluntly,
>>it is intended to be used in cases where your compiler will do something
>>other than what your program plainly asks it to do.
>These statements only acquire truth because the default understanding of
>what the compiler ought to do is very very conservative and tends to reflect
>the most simple-minded way of understanding the code.

A programmer who is at all concerned with portability will code for
a "virtual machine", not for the current accidental hardware.  It is
extremely important that this virtual machine HAVE simple properties;
otherwise it becomes practically impossible to write correct code for
it.  Matters are somewhat confused in C because its virtual machine
has some properties that have deliberately fuzzy specifications; this
was intended to permit more efficient realizations of the virtual
machine on actual hardware, but it causes trouble when programmers
don't clearly understand this issue.

lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) (04/10/88)

In article <765@xyzzy.UUCP>, meissner@xyzzy.UUCP (Michael Meissner) writes:
|Then where were you?

Right here in sunny Columbus Ohio.

|Seriously, yes the ANSI C committee is top heavy
|with implementors, but very few users have ever come to the meetings.
|We do have a few users (around 8 out of 45ish voting members).  In fact,
|one of the "users" spent his own money to attend.

I would have loved to participate, but circumstances
prevented it.  Most others users must be in the same boat.

AT&T was represented so it probably would have been improper
for me to do so independently, I will write to ANSI though.

Of course vendors are usually heavy users too, but I don't
ever recall AT&T formally asking developers throughout the
company for input into the standardization process.  Noone here
had any say in it.  Too bad, I think AT&T is going to pay through
the nose in the long run if and when it ever switches to ANSI-C.
People have a hard enough time learning to use C effectively now.

-- 
Larry Cipriani, AT&T Network Systems and Ohio State University
Domain: lvc@tut.cis.ohio-state.edu
Path: ...!cbosgd!osu-cis!tut.cis.ohio-state.edu!lvc (weird but right)

wes@obie.UUCP (Barnacle Wes) (04/11/88)

In article <48767@sun.uucp>, guy@gorodish.Sun.COM (Guy Harris) writes:
| It is worth noting, for example, that there is no guarantee that "++mutex"
| is an atomic operation.  It is, in fact, worth noting that even if "extern
| volatile char mutex;" was used, there would be no guarantee that "++mutex"
| is atomic.  In all cases, for example, "++mutex" takes an instruction to
| load "mutex" into a register, an instruction to increment it, and an
| instruction to store it, on a SPARC.  The same would be true of any other
| architecture lacking an instruction performing an "add 1 to memory"
| operation.

Another good reason NOT to use a SPARC for anything other than a
paperweight.  On a reasonable processor like the M68000, `++mutex'
becomes an atomic operation like `addq	#1,mutex'.

| This is a real problem; there were some mildly entertaining bugs on Sun-4
| caused by statements such as "++mutex;" in the kernel not being surrounded by
| "spl" calls.

Did you get these bugs squashed, or will you relase the Sun-4 SunOS
with them intact?
-- 
    /\              -  "Against Stupidity,  -    {backbones}!
   /\/\  .    /\    -  The Gods Themselves  -  utah-cs!utah-gr!
  /    \/ \/\/  \   -   Contend in Vain."   -  uplherc!sp7040!
 / U i n T e c h \  -       Schiller        -     obie!wes

wes@obie.UUCP (Barnacle Wes) (04/11/88)

In article <7794@alice.UUCP> dmr@alice.UUCP writes:
>Has anyone else noticed that a lot of the more peculiar things that X3J11
>has added (volatile, and especially noalias) are there for the
>benefit of compiler writers and benchmarkers, and not for the user?

I read a column a few weeks ago that commented on the dangers of
creeping "benchmarkism" (my phrase).  It was either P.J. Plaugher's
column in Computer Language, or Stan Kelly-Bootle's column in Unix
Review.  The author stated that many of the current MS-DOS compiler
implementors have become so obsessed with benchmark times, their
compilers have become almost unusable.

It seems the compilers are now doing things like unrolling loops with
constant bounds, and generating in-line code for what are supposed to
be library routines, like strcpy and memcpy.  This makes for much
faster benchmarks, but makes large (source) programs generate such
large object files that they no longer fit in the target systems'
memory space.
-- 
    /\              -  "Against Stupidity,  -    {backbones}!
   /\/\  .    /\    -  The Gods Themselves  -  utah-cs!utah-gr!
  /    \/ \/\/  \   -   Contend in Vain."   -  uplherc!sp7040!
 / U i n T e c h \  -       Schiller        -     obie!wes

mangoe@mimsy.UUCP (Charley Wingate) (04/11/88)

There seems to be a spurious issue over portability here.  It would seem to
me to be foolish to set up a standard only in the interests of portability,
as though the language so standardized would not still be used in situations
where there is no issue of portability.

In any case, I have problems with Doug's notion of simplicity, because it is
not the only such model which "makes sense."  His model appears to be highly
operational; I intuit that his view is along the lines of "`a<-b' means
 `pick up value from b and put it in a'".  But there are other models, and
in particular, the one that matters is the one in which a concurrent program
is more complex than one which is a single process.  Why?  Because this
model is the one which concerns itself about "what is happening."
Optimizers have to have information given them to tell them when they can
rely on a simple semantic model of computation, and when they have to fall
back to a purely operational model whose semantics are much more complex.
Pre-standard, this notion is hidden outside the code, in optimization flags.

C. Wingate

guy@gorodish.Sun.COM (Guy Harris) (04/16/88)

>     /\              -  "Against Stupidity,  -    {backbones}!
>    /\/\  .    /\    -  The Gods Themselves  -  utah-cs!utah-gr!
>   /    \/ \/\/  \   -   Contend in Vain."   -  uplherc!sp7040!
>  / U i n T e c h \  -       Schiller        -     obie!wes

I guess Schiller is saying here that I'm wasting my time replying to this
article, but:

> Another good reason NOT to use a SPARC for anything other than a
> paperweight.  On a reasonable processor like the M68000, `++mutex'
> becomes an atomic operation like `addq	#1,mutex'.

Well, there would appear to be a hell of a lot of "unreasonable" processors
out there, such as most RISC machines, since they tend to be load/store
architectures with only register-to-register arithmetic.  You can stick with
your 68K if you wish; I suspect most people will be as happy, if not more
happy, with R2000s/R3000s, SPARCs, etc., etc. - or, for that matter, IBM 370s,
etc., etc., etc..

"++" isn't guaranteed to be atomic.  Period.  End of discussion.  The people at
e.g. MIPS and Sun seem to be able to deal with this; if you can't, that's your
problem.

> Did you get these bugs squashed, or will you relase the Sun-4 SunOS
> with them intact?

We fixed all the ones we ran into; none of those are in the first customer ship
version of Sys4-3.2L.

ray@micomvax.UUCP (Ray Dunn) (04/16/88)

In article <7794@alice.UUCP> dmr@alice.UUCP writes:
>Since a good many messages have ardently defended the 'volatile'
>type qualfier, it might be worth pointing out a few things.
>....
>1)  Accessing memory-mapped device registers
>....
>I have no real gripe about the first; I just think it is unnecessary.
>It seems just as reasonable for purveyors of optimizing compilers for machines
>with memory-mapped IO to have a compiler flag that says "please
>be cautious about cacheing things in this routine."
>Alternatively, they could accept a #pragma in the code.

In fact, as compilers these days are often written for *cpu's* rather than
*machines*, and the same cpu can be used in many machine architectures, then
it is important to realize that any machine built from a component cpu has
the capability of memory mapped I/O.

There are many machine architectures out there which use memory mapped I/O
even though the cpu has I/O instruction capability.

[did I hear someone say "and vice-versa"? (:-)]

On the subject of shared memory etc, doesn't the ability to ensure that all
references to a variable actually compile to references to "that" memory
location go a long way to providing a useable tool in what is most-likely
a machine dependant situation *anyway*?

Ray Dunn.  ..{philabs, mnetor}!micomvax!ray

john@frog.UUCP (John Woods, Software) (04/16/88)

In article <144@obie.UUCP>, wes@obie.UUCP (Barnacle Wes) writes:
> In article <48767@sun.uucp>, guy@gorodish.Sun.COM (Guy Harris) writes:
> | It is worth noting, for example, that there is no guarantee that "++mutex"
> | is an atomic operation.
> Another good reason NOT to use a SPARC for anything other than a
> paperweight.  On a reasonable processor like the M68000, `++mutex'
> becomes an atomic operation like `addq	#1,mutex'.
> 
Bad news.  "addq #1,mutex" is NOT atomic on an MC68000 processor, reasonable
or not.  If you have a multiprocessor, it is easy for another processor to
sneak in between the read bus cycle and the write bus cycle and drop another
value into mutex (it may lose, but it will think it won).  That is why the
68000 has the TAS instruction; TAS does NOT release the bus between the
read and the write cycle.

I would be interested to know how one does multi-processor locking on a
SPARC, however (or other RISC processors).  Anyone who *knows* care to
comment?

--
John Woods, Charles River Data Systems, Framingham MA, (617) 626-1101
...!decvax!frog!john, ...!mit-eddie!jfw, jfw@eddie.mit.edu

"Take Greg Nowak.  He's divisible by 59."	- Not Matt Crawford

friedl@vsi.UUCP (Stephen J. Friedl) (04/16/88)

In article <144@obie.UUCP>, wes@obie.UUCP (Barnacle Wes) writes:
> In article <48767@sun.uucp>, guy@gorodish.Sun.COM (Guy Harris) writes:
> | It is worth noting, for example, that there is no guarantee that "++mutex"
> | is an atomic operation.
> | [SPARC uses three instructions: load+inc+store]
> 
> Another good reason NOT to use a SPARC for anything other than a
> paperweight.  On a reasonable processor like the M68000, `++mutex'
> becomes an atomic operation like `addq #1,mutex'.

     A single instruction is no guarantee of atomicity either.
The VAX allows an increment instruction -- "INC mutex" -- but it
is not necessarily atomic; you need ADAWI (Add Aligned Word,
Interlocked) for that.  The VAX provides a half a dozen
instructions like this, designed for synchronized shared access,
and the docs say they are needed.  The WE32100 (in the AT&T 3B2)
has SWAPBI (swap bytes interlocked) instructions to do the same
kind of thing, so I surmise that instructions are not atomic
either.

     I know nothing about how the Moto works, but with today's
high-performance pipelined processors sharing memory with so many
kinds of other processors (DMA, I/O, math, etc.), relying on all
instructions being atomic is probably naive; it will just be
harder to track down where the mutex bugs are.

-- 
Steve Friedl   V-Systems, Inc.   "Yes, I'm jeff@unh's brother"
friedl@vsi.com  {backbones}!vsi.com!friedl  attmail!vsi!friedl

henry@utzoo.uucp (Henry Spencer) (04/17/88)

> | It is worth noting, for example, that there is no guarantee that "++mutex"
> | is an atomic operation...
> 
> ... On a reasonable processor like the M68000, `++mutex'
> becomes an atomic operation like `addq #1,mutex'.

Hee hee.  You haven't read the hardware specs for the 68000 carefully.
The ADDQ instruction does two bus cycles, and as I recall it there is no
guarantee that something else (like, say, another processor) can't get
the bus in between.  If I recall correctly, the *only* read-modify-write
instruction that is *guaranteed* atomic on the 68000 is TAS, which is odd
enough that compilers are most unlikely to generate it.  (Actually the
atomicity of even TAS is somewhat subject to hardware details, but it has
a much better chance of being atomic than ADDQ.)
-- 
"Noalias must go.  This is           |  Henry Spencer @ U of Toronto Zoology
non-negotiable."  --DMR              | {ihnp4,decvax,uunet!mnetor}!utzoo!henry

ray@micomvax.UUCP (Ray Dunn) (04/19/88)

This discussion, like many in comp.lang.c, once again seems to be revolving
mainly around issues of portability.

As I tried to say in a previous posting, if *any* aspect of the 'C'
language has *less* to do with portability than "volatile" has, then please
let's hear about it!

If we are to continue to use 'C' as a system programming language on *real*
machines, with *real* issues of hardware anamolies and performance goals,
then issues in addition to portability must be given their rightful place
when discussing enhancements.  Amongst these issues is the ability of the
language to interface with real hardware architectures (whether some of us
would regard these as "esoteric" or not).

In a system programming environment there is no need for 'C' to hide these
architectures from the programmer through syntactic sugars, it must however
provide the tools to manipulate them.

To the statement that somehow "volatile" is a mistake because 'C' does not
consider other requirements of multi-programming, synchronisation etc., why
do we have to eat the whole cake at once?  Let's make a start with the
facilities we need now *and can implement easily*.

Did we all wait until ANSI had completed its "standardization" before using
'C' in the first place?  (:-)

DMR made a very revealing statement in his argument against volatile which
said something to the effect that it was only required to ensure an optimising
compiler did what everyone visualized the compiler was doing anyway.

I think that this dates Dennis' visualization of what compilers do, and I
must admit, I fall into the same category (and time-span).

I do not believe however that that visualization is valid any longer.
Compilers should increasingly be expected to produce code far from the
traditional statement-by-statement and variable-by-variable translation.

If this is to be the case and 'C' is not to generate into purely an
"application" programming language, then when the programmer *requires* that
an architecture specific feature be used that the programmer is fully aware
of, the language should give him the tools to specify it.

In response to the general point that 'C' cannot handle multi-programming,
co-routines, semaphores, etc:

As was shouted from the back of the bus as the tour guide announced,

"We are now *passing* the oldest pub in the city".

"Why??"


Ray Dunn.  ..{philabs, mnetor}micomvax!ray

tim@amdcad.AMD.COM (Tim Olson) (04/21/88)

In article <2182@frog.UUCP> john@frog.UUCP (John Woods, Software) writes:
| In article <144@obie.UUCP>, wes@obie.UUCP (Barnacle Wes) writes:
| I would be interested to know how one does multi-processor locking on a
| SPARC, however (or other RISC processors).  Anyone who *knows* care to
| comment?

The Am29000 has a "loadset" instruction, which loads a register from a
memory location, then sets that memory location to all-ones.  This
sequence is non-interruptable, and the *LOCK pin is asserted throughout
the entire transaction.

	-- Tim Olson
	Advanced Micro Devices
	(tim@amdcad.amd.com)