HELLER@cs.umass.EDU.UUCP (03/23/87)
> From: on Monster Island <ihnp4!gorgo!bsteve@ucbvax.berkeley.edu> > > NOW for the fly (splat). > QIO has 9-countum-9 arguments in order to do all of this, yuck. The reason > for this is that since you can't get a real return status from the function, > you have to put the return data asynchronously into an i/o status block > and set an event flag to tell the process that the i/o completed. All of this > combined with the general purpose nature of QIO make for this inconvenience. > (Actually QIO[W] takes 12 arguments: six fixed purpose arguments (EFN, chan, func, iosb, astadr, astprm) and six device/function dependent args (p1-p6).) I would not consider this inconvient: for "standard" sorts of things (simple read and write), one can allways define macros (VMS supplies ones for Macro-32 (assembly) and Bliss-32 (DEC's system programming language). > You may be asking yourself "What the hell does all of this have to do with > the structure and mechanism of fork()?" Well... under the same OS's there > is no fork(). They instead us a system service called CREPRC. This function > is very similar to the OS9 fork(). Existing input,output,error file > descriptors may be passed to the created process, but no others. In fact > no other portion of the parent process is actually shared with the child > and must be created anew for the new process. This greatly increases the > overhead of process creation. Once again (like QIO) the large number of > parameters passed to the function can be an inconvenience. Oh yes, it is > also SLOW. > I suspect that the this cost is probably not much greater than the cost of fork() + exec() + all of the other setup stuff commonly done under UNIX. Also, under VMS, with things like QIO & ASTs, there tends to be much less need to call CREPRC. DEC optimized things differently than AT&T/Berkeley. I don't know whether CREPRC is slow due to its added arguments or simply because VMS is just slow at process creation - I supect the latter. Also, VMS is probably not a good model for *small* computers, after all it is designed for *big* machines in a mainframe-type environment. Much of the extra stuff in VMS's CREPRC is not really appropriate for a *SINGLE-user*/MULTI-tasking system anyway: things like privileges, protection, and quotas. Very likely, this is where most of the overhead is eaten up (I haven't looked at the source 'fich). Also, UNIX's fork() really wants not only a MMU but virtual memory with copy on reference (which is what makes it fast under UNIX and probably why OS9's fork() does not "copy" the process's image). With virtual memory, all that fork() has to do is copy the page table entries (marking all pages as copy-on-referene) and make sure all of the parent's modified pages have been written to the paging file - thus when the child starts running, its code, data, and stack are paged in from the parent's paging area and will get paged out to a new paging area. Any parts of the parent not used by the child are not copied to memory (never paged in). I suspect that any implementation of UNIX's fork() *without* virtual memory (but with a MMU), will be as slow as (if not slower than) a CREPRC service call, espcially if the child process's program is smaller than the parent and does not need *ALL* of the parent's core image - it will be faster to load a small program than copy a big one. ---------------------------------------- Note that dispite VMS's inappropriateness from a small system point of view, many of its features (like QIO and CREPRC) are probably usefull/desireable and can probably be easily implemented. These functions need not be as complex or have as many layers as VMS does (i.e. QIO need not have three flavors of I/O (virtual, logical, & physical) and CREPRC doesn't need to create as much new context glop or bother with quotas, etc.). It seems to me that an O/S with *streamlined* variations of QIO and CREPRC would probably be suffient. Note: under VMS the QIO service (and other services) take something called an AST (Asynchronious Software Trap), which is a routine called upon I/O completion (or other event) - this routine is part of the process that established it and runs in the context of that process. Typically, this routine provides much the *same* functionallity as a UNIX fork() would, without having to create a new process, at least for implementing I/O servers or timed events (the main process fires up the QIO requests or timer queue requests and then either hybernates or goes about its business - when the I/O completes or the timed event occurs, the "server process" (the AST) is invoked and it services the event). This sort of function does not even need an MMU, since it is still part of the "parent" process. This is actually easy to implement and has a very small overhead (need to store a *small* structure containing the AST address and some context info). Robert Heller ARPANet: Heller@CS.UMass.Edu BITNET: Heller@UMass.BITNET BIX: Heller GEnie: RHeller FidoNet: 101/27 (Dave's Fido, Gardner, MA) or 101/147 (Orange Fido, Orange, MA) CompuServe 71450,3432 Local PV VAXen: COINS::HELLER UCC Cyber/DG: Heller@CS