On 06/07/2021, Larry McVoy <lm(a)mcvoy.com> wrote:
I wasn't completely right 20 years ago but I was close. I'm tired,
if you want to know where I'm wrong, ask and I'll tell you how I
tried to get Linus to fix it.
In general, Rob was on point. He usually is.
I've never been a fan of clone(). It always strikes me as something
that seems like an elegant simplification at first, but the practical
realization (on Linux that is) requires several rather ugly
library-level hacks to make it work right for typical use cases.
UX/RT will use the "processes are containers for threads" model rather
than rfork()/clone() since that's the model the seL4 kernel basically
uses (in a very generalized form with address spaces , capability
spaces, and threads being separate objects and each thread being
associated with a capability space and address space), and it would
also be slightly easier to create the helper threads that will be
required in certain parts of the IPC transport layer.
The base process creation primitive (efork(), for "empty/eviscerated
fork") will create a completely blank non-runnable child process with
no memory mappings or file descriptors, and return a context FD that
the parent can use to manipulate the state of the child with normal
APIs, including copying FDs and memory mappings. To actually start the
child the parent will perform an exec*() within the child context
(either a regular exec*() to make the child run a different program,
or a new eexec() function that takes an entry point rather than a
command line to run the process with whatever memory mappings were set
up), after which point the parent will no longer be able to manipulate
the child's state.
This will eliminate the overhead of fork() for spawning processes
running other programs, but will still allow for a library-level
fork() implementation that has comparable overhead to traditional
implementations. Also, it will do what Plan 9 never did and make the
process/memory APIs file-oriented (I still don't get why Plan 9 went
with a rather limited anonymous memory API rather than using
memory-mapped files for everything).
Also, we're straying a bit from historical Unix here and should have
probably moved to COFF several messages ago.