On Sat, 2008-05-24 at 15:39 -0400, Greg Freemyer wrote: [....] > I also think it is useful to realize that UNIX was basically designed > for systems that have a MMU even though low-end systems in the late > 70s / early 80s did not have them. The first ones (also before) didn't have a MMU and the first versions of "Unix" ran on it. > I believe there were implementations that ran on 286 based hardware > without MMUs way back then, but they were very kludgy and definately > not the design target for UNIX. Of course they were as that was common hardware in the 60s and (earlier?) 70s. > With an MMU even if a multi-megabyte app is forked, a majority the > memory pages are initially shared between the parent and child. A That came later - first via a separate vfork() Sys-Call - also on non-MMU systems - which didn't copy anything and meant to be used if you execv() afterwards anyways. Copy-on-write was implemented later on MMU-systems (and fork() and vfork() were more or less "merged" as there was no real need to separate it). > copy on write system is used to create individual RAM pages if either > the parent or the child writes to a specific shared RAM page. > > Thus the fork call is very efficient and effectively does the minimum > amount of work necessary to create a new process from a parent > process. Therefore if exec is immediately called by the child, little > wasted effort was caused by it being two discrete steps as opposed to > one larger step. ACK - in that area is that the somewhat optimal situation. But I don't think that Kernighan and Ritchie had that goal in their initial design in the 60s;-) > And as someone else said with current implementations you have a lot > of control of exactly what is carried over from parent to child via > the clone call and thus can optimize the process. Conceptually fork() and execve() are two totally different (and independent) operations: - fork() simply creates a new process. And the simplest implementation just lets that function return twice - once in the original - "parent" - process and one in the new - "child" - process with different return values. - execve() loads the code of a another (or the same) process and starts at the main() function. Yes, it actually starts before somewhere else but for normal programmer it starts usually at the main() function. Of course you can argue that "start another program" could be combined in one Sys-Call but that won't kill the need of the 2 above Sys-Calls as you need it for other actions like "restart the same daemon on top of the old" (after a configuration change or after a change of the binary) or simply the "I want a separate process for this sub-task in my application". The latter could be done with threads but that implies a thread lib (and not all systems - especially small ones - have or want one) and you don't have some kind of "snapshot" feature on the memory as the sub-thread could change data in the main thread (or so need synchronization with all potential problems like "deadlock"). Or think of a shell with a piped commandline (as in `ls -als | grep '.c$' | wc -l` for a simple example. Yes, that could be done more simple with "grep -c", etc.). The shell has actually to do something specific in the child processes after the fork() and before the execve(). As a simple exercise: Write a "startbinary()" function (somewhat similar to system(3), popen(3) is of no help here) simply combining fork() and exec() and implement with that function a piped commandlines (and use it with more than one pipe). Run that under `strace` and compare the output with the same commandline under `strace sh -c` (and it could be more efficient - using less sys-calls - than the typical "sh -c"). And the performance loss of 2 sys-calls instead of one on starting another program is IMHO not really measurable - not even if you have everything in a RAM disk, hot caches, etc. Bernd -- Firmix Software GmbH http://www.firmix.at/ mobil: +43 664 4416156 fax: +43 1 7890849-55 Embedded Linux Development and Services -- To unsubscribe from this list: send an email with "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx Please read the FAQ at http://kernelnewbies.org/FAQ