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