[comp.sys.ibm.pc] Fork and process creation

cgeisler@water.waterloo.edu (Craig Eisler) (05/26/89)

In article <593@rna.UUCP> kc@rna.UUCP (Kaare Christian) writes:
>"An initial Send", whatever that is, must dupicate I/O connections,
	     ^^^^
>signal handling and other aspects of the original process' state,

All of these things have no place in a process creation primitive.
Create() is the type of primitive the kernel needs to spawn a
new process.  Duplication of I/O connections is a job for a file
server, not the kernel.

>Forks make it easy to have pipes (cheapo, flexible ipc)
						    ^^^
Pipes are a nice feature, but they are anything but cheap.
They are file I/O.  Too damn slow.  Since you mention IPC, I
assume you know what Send,Receive, and Reply are.  If you want 
cheap communication, that is what you use.  And you do not need
fork to implement pipes. 

>Unix is still the only system that allows most programs to work together
>easily, using ad hoc connections. Fork is an essential part of that
>flexibility.

I disagree.  Fork is an unnecessary primitive.  Of course, the UNIX
kernel is filled with unnecessary primitives (270 or something similar).

>And now a few numbers. How fast is "fast enough" for fork? 
>[times omitted]

At a cost of 35ms for a fork, you can forget about using it in any
kind of real time environment.

In an operating system I implemented on a intel 186, process creation
was 2.8 ms.  And this was barely good enough for arbitrary process
creation while trying run a system of trains in real time.

Currently I am involved with the Multi-processor Systems Group here
at the university, and we are designing a firmware (microcoded) kernel
to run 4 68030's.  There will be no fork, only process creation.
All other features of fork have no reason for being in the kernel.

craig
-- 
Craig Eisler, Applied Math, University of Waterloo
"Either way, I'm afraid to try it" - Calvin.

madd@bu-cs.BU.EDU (Jim Frost) (05/26/89)

In article <2361@water.waterloo.edu> cgeisler@water.waterloo.edu (Craig Eisler) writes:
|In article <593@rna.UUCP> kc@rna.UUCP (Kaare Christian) writes:
|>"An initial Send", whatever that is, must dupicate I/O connections,
|	     ^^^^
|>signal handling and other aspects of the original process' state,
|
|All of these things have no place in a process creation primitive.
|Create() is the type of primitive the kernel needs to spawn a
|new process.  Duplication of I/O connections is a job for a file
|server, not the kernel.

Not so, if the process creation is supposed to duplicate file
descriptors (ala UNIX).  File descriptors (again, under UNIX) refer to
I/O, but not necessarily FILE I/O.  Thus they are out of the range of
a file server.

|>Forks make it easy to have pipes (cheapo, flexible ipc)
|						    ^^^
|Pipes are a nice feature, but they are anything but cheap.
|They are file I/O.  Too damn slow.

Wrong.  Pipes *can* be, but they don't *have* to be.  Usually it's
just a buffer.  Generally all that's involved in piping between
processes is a copy from one process' area into the buffer, then a
copy into the other process' area from the buffer.  It's possible to
cut down on the copies but it's too painful in many circumstances to
bother.  On many architectures copies are generally one or two
instructions anyway, not a loop.

|Since you mention IPC, I
|assume you know what Send,Receive, and Reply are.  If you want 
|cheap communication, that is what you use.

"A rose by any other name".  It makes no difference to me if "send" is
called "write" and "receive" is called "read".  Possibly it's
overloading the interface, but it's sure easy to figure out.

|And you do not need
|fork to implement pipes. 

No, but it makes the semantics much simpler.  Having worked under a
variety of systems which don't have a fork construct, let me tell you
I prefer it.

|>Unix is still the only system that allows most programs to work together
|>easily, using ad hoc connections. Fork is an essential part of that
|>flexibility.
|
|I disagree.  Fork is an unnecessary primitive.  Of course, the UNIX
|kernel is filled with unnecessary primitives (270 or something similar).

Fork is not unnecessary.  Many people would argue that it's not
enough.  There "should" be at least three primitives for starting
another process:  fork(), spawn(), and thread().  (Note that exec()
doesn't start another, just overlays a current one.)  Which is ideal
depends on your requirements, thus you "should" have all of them.
spawn() isn't a primitive (fork() exec() means spawn()) but it has
much lower overhead if it's implemented as one.

As for "filled with unnecessary primitives", I think you'll find that
there are very few real "primitives" in the UNIX environment.  There
are a lot of system calls (270 seems a bit high, are you sure you're
not counting library routines?), many of which are used for features
such as networking, terminal control, and filesystem manipulation.
Most commercial operating systems have many more "primitives" than
UNIX, and usually each of these "primitives" has a plethora of
options.  Most non-UNIX system programmers I've run into are unhappy
at the lack of UNIX system calls.

|In an operating system I implemented on a intel 186, process creation
|was 2.8 ms.  And this was barely good enough for arbitrary process
|creation while trying run a system of trains in real time.

Probably you should outline the capabilities of your operating system
before you give these numbers.  My bet is that it supports far fewer
features than UNIX (did it network?  multiuser?  filesystem support?
etc).  Additionally, it probably is very Intel-specific (ie all or
most in assembly, little chance of porting with minimal changes) to
get times like that.  Not a good comparison.

Compare UNIX's times with those of comparable commercial OS's and I
believe you'll find that it does better than most.

[followups redirected to comp.unix.wizards]

jim frost
software tool & die
madd@bu-it.bu.edu

bobmon@iuvax.cs.indiana.edu (RAMontante) (05/26/89)

cgeisler@water.waterloo.edu (Craig Eisler) <2361@water.waterloo.edu> :
-
-Pipes are a nice feature, but they are anything but cheap.
-They are file I/O.  Too damn slow.  ...

[minor nit, maybe...]  I think you say this because you're thinking of
MSDOS pipes, which are just temporary files and require disk I/O.  In
Unix a pipe involves file system calls (so it "looks like" low-level
file I/O to a process), but the writes and reads never go beyond the
file buffer in memory.  This eliminates the major bottleneck and makes
a LOT more sense, given the ability to set the buffer size.

paradis@xenna.Encore.COM (Jim Paradis) (05/27/89)

bobmon@iuvax.cs.indiana.edu (RAMontante) writes:
>In Unix a pipe involves file system calls (so it "looks like" low-level
>file I/O to a process), but the writes and reads never go beyond the
>file buffer in memory.

Point of information: in System V, pipes use the normal buffer cache
and are in fact assigned filesystem blocks to use.  If disk I/O 
gets REALLY hot && heavy then it is conceivable that a pipe will
indeed incur disk I/O.  Of course, if this gets to be the case then
your system is probably performing like a dog already...

Jim Paradis	paradis@encore.com		508-460-0500
(My other .signature is a witty saying)