Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!cmcl2!brl-adm!adm!aglew%mycroft@gswd-vms.Gould.COM From: aglew%mycroft@gswd-vms.Gould.COM (Andy Glew) Newsgroups: comp.unix.wizards Subject: Re: Free Software Foundation (was: R Message-ID: <9407@brl-adm.ARPA> Date: Mon, 21-Sep-87 09:42:42 EDT Article-I.D.: brl-adm.9407 Posted: Mon Sep 21 09:42:42 1987 Date-Received: Tue, 22-Sep-87 01:58:53 EDT Sender: news@brl-adm.ARPA Lines: 122 PROCESS TEMPLATES ----------------- ..> Cost of fork/execs, ..> Providing a fork/exec call ..> etc. An earlier poster is correct in saying that a combined fork/exec call is not as convenient as doing a fork followed by an exec, because the typical use of vfork is if( fork() == 0 ) { /* Copy parent process */ dup2(..) /* Manipulate parts of state to be inherited by new program */ exec(..) /* Bring new program in */ } I wonder, though, if we cannot divide this up into two operations?: (1) setting up a process (2) dispatching the process. (1) may be cheap on some systems, expensive on others. But (2) can probably be made inexpensive on all systems. There is probably a large class of programs where all the child processes that are likely to be used can be set up in advance, under no time constraints; and when you actually need them almost all the work has already been done, so you just set the PC and go. I call this idea "process templates", and introduce a data structure of the same name. The process template data structure contains slots for all the things that a process has to have - memory maps, descriptor tables, etc. - which you can fill in at different times. Or, you can provide options to copy everything appropriate from one process template to another... Types and Operations: typedef ... proctempT; extern proctempT CurrentProcess; /* The present state of the current process */ proctempT pt_new(); /* Returns a new, empty, process template */ pt_addmemorysegment(pt,memseg); /* Link a memory segment to a process template */ pt_open(pt,path,options,mode); /* Opens a file placing the descriptor in the process template pt */ pt_setpc(pt,pc); /* Set program counter */ pt_setsp(pt,sp); /* Set stack pointer */ pt_loadexecutable(pt,execfile); /* Load executable into template */ pid = pt_dispatch(pt) /* dispatch a process template as a process - error if not all features are set up */ pt_overlay(pt) /* Replace the current process by the new template */ oldpt = pt_wait() /* Wait on a child process, receiving its process template */ pt_copyunsetfeatures(ptfrom,ptto) /* copy all necessary but unset aspects of a process */ pt_linkunsetfeatures(ptfrom,ptto) /* link instead of copy */ Implementing fork/exec: fork() { proctempT childpt = pt_new(); int childpid; pt_copymemory(CurrentProcess,childpt); pt_linkdescriptors(CurrentProcess,childpt); pt_copyunsetfeatures(CurrentProcess,childpt); pt_setpc(&ChildFork); childpid = pt_dispatch(childpt); return childpid; ChildFork: /* ok, so you would probably use a longjump... */ return 0; } exec(execpath) { proctempT execpt = pt_new(); pt_loadexecutable(execpt,execpath); pt_linkunsetfeatures(CurrentProcess,execpt); pt_overlay(execpt); } Now, why would you do all this work? So that you can split out the functionality. Eg. in a math code on a multiprocessor, you want to have N processes working on a several loops, with serial code in between. Instead of repeatedly copying state in forks (or even tforks), set up all your process templates at the beginning of the program linked to share everything with the parent, and just change the pc i them when you need them. In addition, if the system guarantees that all processes created with pt_new() can be pt_dispatch'ed, then you don't have to worry about error conditions or deadlocks if one of the processes you wanted to spawn cannot be sent off. Implementation The process templates could probably be a combination of a kernel data structure, for fields that we cannot allow the user to put just anything in, and a user data structure for fields that are easy to check at dispatch time. The second class of fields could be directly manipulated without system calls.