Comment by kragen

4 years ago

The PDP-11 had segment base registers and memory protection, so it wasn't necessary to swap out one process to run another one at the same (virtual) address. It didn't have paging, so it couldn't swap out part of a segment. I think it's true that PDP-11 fork() would stop the process to make a copy of the writable segments, but it didn't have to "checkpoint" the process to a disk or tape. Are you talking about the PDP-7? I don't know anything about the PDP-7.

I agree about vfork(), since I haven't seen a system with segment base registers and no paging in a long time, and about clone(). Unfortunately it's true that clone() (which came from Plan9) has made POSIX threads difficult to support.

What's the L4 approach? Construct the state of the process you want to run in some memory and then use a launch-new-thread system call, then possibly relinquish access to that memory?

> Are you talking about the PDP-7?

Yes

> Unfortunately it's true that clone() (which came from Plan9) has made POSIX threads difficult to support.

clone was literally designed to support posix threads.

> What's the L4 approach?

Capabilities over all of the kernel objects so user space can do safe brain surgery on them. Since everything is capability based including the cap tables you end up duping a cap table, allocating a non running thread, setting registers, and attaching duped cap table. Four syscalls in the minimal case, but it's l4 so they're fairly cheap. Total disclosure, one of my side projects is a kernel with caps and a first class VM to do that in one syscall amortized.

  • I see. Maybe that explains why on PDP-7 Unix programs would exec the shell instead of terminating the process; swapping your process out to disk or tape can't have been very fast. But without an MMU what else could you do?

    Plan9 clone() was not designed to support POSIX threads; IIRC they didn't exist and Plan9 didn't support POSIX. Wasn't Linux clone() mostly a copy of it?

    The L4 approach sounds pretty reasonable; not as convenient as fork() in the common case but not as much of a pain as, I don't know, opening a pty or opening an X11 window. I guess L4 syscalls are a bit pricier post-Spectre. How are you going to handle atomicity in your one syscall?

    • > Plan9 clone() was not designed to support POSIX threads; IIRC they didn't exist and Plan9 didn't support POSIX. Wasn't Linux clone() mostly a copy of it?

      Plan9 doesn't have clone(). When they say clone was designed after plan 9, they just mean the general namespacing (which was not configured from their fork or new_thread equivalents). Linux clone was very much designed to support posix threads.

      > The L4 approach sounds pretty reasonable; not as convenient as fork() in the common case but not as much of a pain as, I don't know, opening a pty or opening an X11 window. I guess L4 syscalls are a bit pricier post-Spectre.

      Yeah, they got more expensive having to hide kernel address space layout.

      > How are you going to handle atomicity in your one syscall?

      Capabilities to bpf style programs that look like any other kernel objects and can call other kernel objects, combined with a scheme where mutex/spinlock wrapped objects have a locking order declared upfront that can be statically checked, combined with RCU primitives that the VM program verifier knows about and can make guarantees about. I'm not quite happy with the locking and RCU interfaces at the moment though, it feels like there's a more general solution, but each I've come up with has some real sharp edges. : \

      1 reply →