[comp.bugs.sys5] What's a system call

andys@ulysses.homer.nj.att.com (Andy Sherman) (05/10/89)

In article <1350@frog.UUCP> john@frog.UUCP (John Woods) writes:

   "system call" is not well enough defined to be the determinant of whether
   errno is usable or not (after all, why IS open() a system call, and why
   IS NOT fopen() a system call?).  What you ought to rely on is what a common
   manual documents.

A system call is a subroutine documented in Chapter 2. :-)

Actually, a system call is an entry point which is a one-for-one mapping to a
particular kernel service.  Open(2) is a system call which returns a file
descriptor, which is a kernel data structure.  Fopen(2) on the other hand
returns a non-kernel data structure called a stream, which is typedefed as
FILE in stdio.h.  One field in the structure is the file descriptor, and one
piece of fopen is a call to open to get that file descriptor.  System functions
are the primatives which are used either by themselves or implicitly by 
subroutines which add some value.  (For another example, compare the 
execve(2) system call with the various execxxx(3) subroutines.)
-- 
Andy Sherman/AT&T Bell Laboratories/Murray Hill, NJ           *NEW ADDRESS*
AUDIBLE:  (201) 582-5928                                      *NEW PHONE*
READABLE: andys@ulysses.ATT.COM  or att!ulysses!andys         *NEW EMAIL*
The views and opinions are my own.  Who else would want them? *OLD DISCLAIMER*

guy@auspex.auspex.com (Guy Harris) (05/10/89)

>Actually, a system call is an entry point which is a one-for-one mapping to a
>particular kernel service.  Open(2) is a system call which returns a file
>descriptor, which is a kernel data structure. 

On *some* implementations of the UNIX system interface, "open" is a
system call which returns a file descriptor, which is a kernel data
structure.  I don't think it is in Apollo's DOMAIN/OS (or is that
"Domain/OS"?) implementation, for example.

bill@twwells.uucp (T. William Wells) (05/11/89)

In article <11506@ulysses.homer.nj.att.com> andys@ulysses.homer.nj.att.com (Andy Sherman) writes:
: A system call is a subroutine documented in Chapter 2. :-)

Right you are. And that is the only definition that is meaningful to
a programmer.

: Actually, a system call is an entry point which is a one-for-one mapping to a
: particular kernel service.  Open(2) is a system call which returns a file
: descriptor, which is a kernel data structure.  Fopen(2) on the other hand
: returns a non-kernel data structure called a stream, which is typedefed as
: FILE in stdio.h.  One field in the structure is the file descriptor, and one
: piece of fopen is a call to open to get that file descriptor.  System functions
: are the primatives which are used either by themselves or implicitly by
: subroutines which add some value.  (For another example, compare the
: execve(2) system call with the various execxxx(3) subroutines.)

There isn't a thing in the world requiring fopen to be implemented in
user code. It could just as easily be implemented as a system call.
And in some Unix versions, the different exec calls *are* implemented
all as system calls or as minor variations on a small number of
system calls (that is to say, each is really a small subroutine which
diddles in a slightly different way its arguments and then does one
of a few system calls).

And then consider sleep(). I know of one system where sleep was
implemented as a system call (and documented in section 2) because
the standard version of sleep would hang occasionally. Consider:

	alarm(n);
	pause();

(the guts of sleep) and what happens if the process doesn't run for n
seconds. Have you ever had tail hang on a heavily loaded system? (I
have.) Guess why.

---
Bill                            { uunet | novavax } !twwells!bill

chris@netcom.UUCP (Chris Lakewood) (05/14/89)

In article <913@twwells.uucp] bill@twwells.UUCP (T. William Wells) writes:
]And then consider sleep(). I know of one system where sleep was
]implemented as a system call (and documented in section 2) because
]the standard version of sleep would hang occasionally. Consider:
]
]	alarm(n);
]	pause();
]
](the guts of sleep) and what happens if the process doesn't run for n
]seconds. Have you ever had tail hang on a heavily loaded system? (I
]have.) Guess why.
]---
]Bill                            { uunet | novavax } !twwells!bill

Don't leave us in suspense...  What happens if the process doesn't run for
n seconds?  Actually, the process won't run for at least n seconds unless
it receives some signal.  The pause causes the process to block until a
signal is received.

john@jetson.UPMA.MD.US (John Owens) (05/18/89)

In article <1232@netcom.UUCP>, chris@netcom.UUCP (Chris Lakewood) writes:
> ]	alarm(n);
> ]	pause();
> ](the guts of sleep) and what happens if the process doesn't run for n

> Don't leave us in suspense...  What happens if the process doesn't run for
> n seconds?  Actually, the process won't run for at least n seconds unless
> it receives some signal.  The pause causes the process to block until a
> signal is received.

If the process doesn't run for 'n' seconds *after* the alarm() is
posted and *before* pause() is called, it'll get a SIGALRM (which is,
I think, set to SIG_IGN at that point), not do anything, then call
pause() too late....

-- 
John Owens		john@jetson.UPMA.MD.US		uunet!jetson!john
+1 301 249 6000		john%jetson.uucp@uunet.uu.net

les@chinet.chi.il.us (Leslie Mikesell) (05/19/89)

In article <225@jetson.UPMA.MD.US> john@jetson.UPMA.MD.US (John Owens) writes:

>> ]	alarm(n);
>> ]	pause();
>> ](the guts of sleep) and what happens if the process doesn't run for n

>If the process doesn't run for 'n' seconds *after* the alarm() is
>posted and *before* pause() is called, it'll get a SIGALRM (which is,
>I think, set to SIG_IGN at that point), not do anything, then call
>pause() too late....

Hmmm...  Could this perhaps be why uugetty (SysVr3.1 on a 3b2) sometimes
leaves a port dead and killing it lets a new one start properly.  Maybe
when it sees a uucp lockfile it tries to sleep awhile and check again.
An idle  uugetty would be a likely thing to be swapped out and not
run during the time the time the signal is delivered.


Les Mikesell

danl@cbnewsc.ATT.COM (daniel.r.levy) (05/21/89)

In article <225@jetson.UPMA.MD.US>, john@jetson.UPMA.MD.US (John Owens) writes:
< In article <1232@netcom.UUCP>, chris@netcom.UUCP (Chris Lakewood) writes:
< > ]	alarm(n);
< > ]	pause();
< > ](the guts of sleep) and what happens if the process doesn't run for n
< 
< > Don't leave us in suspense...  What happens if the process doesn't run for
< > n seconds?  Actually, the process won't run for at least n seconds unless
< > it receives some signal.  The pause causes the process to block until a
< > signal is received.
< 
< If the process doesn't run for 'n' seconds *after* the alarm() is
< posted and *before* pause() is called, it'll get a SIGALRM (which is,
< I think, set to SIG_IGN at that point), not do anything, then call
< pause() too late....

There's a way to get around this, so that if more than n seconds elapse
since the calling of alarm(n) before the system gets around to calling
pause(), sleep() will still return.  This is left as an exercise to the
reader.  Anyone with System V Release 2 source code (and possibly earlier, I
don't have it on hand to check) can see for themselves how this is done.

Someone mentioned making sleep() a true system call.  I can see good reasons
for this.  (One reason is to get around the fact that the sleep() code work
around has critical sections, where other signal handlers being invoked at
just the right [wrong?] place within it and doing certain things might cause
a stack botch or other anomalous behavior.)

But guaranteeing that sleep() will not hang forever on a slow system is not it.
-- 
Dan'l Levy                 UNIX(R) mail:  att!ttbcad!levy, att!cbnewsc!danl
AT&T Bell Laboratories
5555 West Touhy Avenue     Any opinions expressed in the message above are
Skokie, Illinois  60077    mine, and not necessarily AT&T's.

dyer@spdcc.COM (Steve Dyer) (05/21/89)

In article <902@cbnewsc.ATT.COM> danl@cbnewsc.ATT.COM (daniel.r.levy) writes:
>Someone mentioned making sleep() a true system call.  I can see good reasons
>for this.

In V6 and earlier UNIXes, sleep() was indeed a system call.  Unfortunately,
its implementation was such that every sleeping process got a wakeup when
a sleep expired.  tout was an int vector (no longs then!) containing the
absolute second at which time the first sleeping process was to wake up.
If that was reached in the one-per-sec part of the clock routine, a wakeup
was performed on tout.  Every process in the sleep system call would check
to see whether ITS timer had expired or not, and if not, go back to sleep.

The address space limitations on the 11/40-class machines probably suggested
this implementation as well as the still-current and more efficient alarm()/
pause() implementation.  Alarm() and pause() weren't introduced until PWB.
They weren't in V6.

-- 
Steve Dyer
dyer@ursa-major.spdcc.com aka {ima,harvard,rayssd,linus,m2c}!spdcc!dyer
dyer@arktouros.mit.edu