maxusers in config file (4BSD) [MILDLY HOT FLAME]

Robert Elz kre at munnari.OZ
Sun Jan 27 11:46:13 AEST 1985


First, please excuse this flame in unix-wizards.  You may feel that
net.flame would be a better choice of group, but (un)fortunately
we don't get this in Australia.  I wouldn't have used it anyway,
as I really do feel that this flame contains at least a basis of
wizardly material.  Remember if you flame at me for flaming here,
you're just compounding my sin.  Also I have waited a couple of
days since this message appeared - supposedly to allow my temper
to cool, all that's its done though is fan the flames...

Now, gloves on, goggles down, away we go.

In article <2622 at umcp-cs.UUCP> chris at umcp-cs.UUCP (Chris Torek) writes:
| > In order to comply with AT&T's restrictions on binary licenses, we've
| > added a maxusers() system call that returns the value from the
| > config maxusers parameter.
| 
| ANOTHER SYSTEM CALL just for ONE STUPID INTEGER?!  What is this anyway?
| How about having a single system call, ``getinterestingkernelnumber'',
| which takes an argument describing which integer to return?

I don't believe this crap!  I'm going to attack it from two angles.

First, there are two ways that you can define "system call" for this
purpose.  The one I feel sure Chris means, is "the number of entries
that aren't nullsys or nosys in the syscall array".  (If I'm wrong
never mind, I'll get to the other one).

On this assumption - WHO CARES???  What difference can it possibly make??
How the syscall array is used by some particular kernel implementation
is surely entirely a matter for that implementation.

The most obvious thing to say first, is that on one view, on a vax
(that's what Ed Gould was referring to in his original posting, I'm sure),
the number of system calls is 1.  It takes an argument telling which
particular function to perform.  Just like Chris wants.  Minimal even!

On a 68k (or a Perkin-Elmer) the number of sys calls is 16,
in most implementations just one of them is used.  Pdp-11's
are a vague area, you can consider there to be 1 or 64 sys calls.
(or 4 or 130 if you want to count the TRAP EMT BPT and IOT instrs
in various ways).

The method that the implementation uses to choose the particular
function to be performed given the particular hardware sys call
instructions available must be one of the most irrelevant matters
for argument of all time.  It used to be material when we all coded
in assembler - maybe Chris still does???

A couple of examples:  most 68k implementations that I've
seen use just one of the "trap" instructions for all kernel
entries.  A particular implementation might decide that as
"read" and "write" are executed orders of magnitude more
often than the other sys calls, they can gain some precious
cpu time by using two of the otherwise unused "trap" instrs
for those functions, give them idealized parameter passing
(eg: all params in registers, so no validation needs to
be done to get the args) and perhaps gain a 100 usecs or so
over the "standard way".  That just might be the edge they
need over the competition.

What would that do to your "sys call counting"?  Are they
two extra sys calls, or not?  They're certainly different
from the standard syscalls.

Another.  There's this processor I know 
	[which I won't name, as this just might be covered by
	non-disclosure - but if I don't tell you which I'm talking
	about, only those people who've already been disclosed to
	are going to recognise this, right?  Also, I'm going to
	change the facts (and introduce some errors that I know
	are here, so don't bother to read this as a precise spec)
	which will further hide things]
which has the clock register in user readable address space.
In the unix implementation for this processor, the "time" syscall
can be "eliminated", and replaced by a little bit of "as" code
that reads the clock register and does the little bit of arithmetic
needed to turn it into unix format.  Much cheaper than the overhead
of a switch to kernel mode.  There's also a register that gives
the cpu time used by the current process.  With that, and by having
all sys calls return the "sys" time used by the process (to the "as"
interface code, that then salts this away somewhere before returning
to the user code), and the "wait" sys call returning the child cpu/sys
times, the "times" sys call can also be done away with.

Do we applaud this implementation for saving two system calls ???

I don't - its probably an intelligent implementation decision,
but nothing more than that.

So, lets drop all this crud about system call counting, eh?
It's simply and totally irrelevant to everything.


Now for the 2nd possible interpretation of "system call".  What
it might be used to mean is a kernel service.  That is, something
provided by the OS implementation to users.

With this definition, "maxusers" is a new sys call, whether its
implemented as a function name in the syscall array in the kernel,
or whether its implemented in a case statement in the
"getinterestingkernelnumber" function in the kernel (which is
in the syscall array).  Its new functionality, and thus
a new system call.

My only remarks about this (I'm not about to get into whether
maxusers() is a useful addition or not) is that if its going
to be done, to the C (or whatever) programmer it MUST appear
as a new function, not as an appendage to some other unrelated
function.

Whether maxusers is implemented as

_maxusers:	.word 0
		chmk	$MAXUSERS
		rts

or

maxusers()
{
	return getinterestingkernelnumber(MAXUSERS);
}

is of the utmost indifference to me, and I suspect to everyone else.
(Ed wasn't explicit in his posting about which of these he had
chosen.  Nor is there any reason he should have been).

Now, why "must" it be a new function?  Why don't C programmers
just use "getinterestingkernelnumber" and save the overhead of
the extra function call?

Well, there are dozens of reasons, some concerned with modularity,
etc, some with allowing the implementation to then choose which
of the above implementation methods to use (and perhaps, on
the cpu I described above, there'll be a "maxusers" register
that programs can read, so to upgrade an 8 user system to a 16
user system its a hardware strapping - and maxusers wouldn't be
a kernel call at all :-)

You might even make noises along the lines of "performing
one function well"...

The one I like best at the minute, is that if a program that uses
the "maxusers" sys call is moved to a host that doesn't have this
sys call, its much easier to make a workaround function than it
is if the program used getinterestingkernelnumber directly.

The way that you're likely to discover the use of a facility that
your system doesn't have is when you compile the program and end
up with a "xxx undefined" message from the linker.  Now if "xxx"
is "maxusers" you just write a little function

maxusers()
{
	return (100);
}

or something, link it in, and you're in business.  If "xxx" is
"getinterestingkernelnumber" then you start gazing through the
code (which might be a big job - consider the case where you're
sent .o files in the right object format, ready to link with
your system libraries!) to try and determine which particular
kernel number(s) the program is using, or you try and write a
simulation function that returns something for all the possible
kernel numbers that might be wanted.

Which would you rather do???


So, lets end forever this absurd phobia that some people have with
system call counting.  (Which is NOT the same thing as saying
that some kernel is too big, or does things it shouldn't ...
which can be a valid point of dispute)

One thing that has galled me for ages at usenix conferences is the
occasional talk given by someone who has added some facility
to the kernel, but who "hasn't added any new sys calls".  Recently
this has been particularly noticeable in AT&T talks for some
reason.  Either functionality has been added or it hasn't.
You can argue about whether its worth it or not, but PLEASE forget
all this NONSENSE about numbers of sys calls.

In fact, its time that we abandoned the distinction between
sys calls and other C library functions completely (that is
between section 2 and section 3), either something is available
to the user level programmer in some lib func, or its not.

Well, this has gone on far too long now, so I'll cease here.
This has eased my conscience a bit, on occasions recently I've
been tempted to rebut some of the absurdity pronounced by
some "experts" in this forum, but have resisted out of courtesy
to the net - without feeling good about allowing misused
cliches go unchallenged.  Now I feel better.  I hope that
you don't feel I've abused the net too much.

If you have stayed with me this long, I thank you, you can now
go onto more boring discussions about ripping off AT&T etc.

Robert Elz				decvax!mulga!kre

ps: its reasonably warm outside today, a total fire ban day
in Victoria (for those of you who know what that means).  I could
probably be arrested for this posting - except I'm indoors :-)



More information about the Comp.unix.wizards mailing list