EtchedPixels / FUZIX

FuzixOS: Because Small Is Beautiful
Other
2.16k stars 271 forks source link

spawn() family of calls #637

Open erkinalp opened 6 years ago

erkinalp commented 6 years ago

spawnve which does not call fork and execve under the hood will prevent unneeded copies.

EtchedPixels commented 6 years ago

Except that we have pretty much nothing that could use it. I think vfork() would be a better option and that is on my longer term list. The posix_spawn functions can then be written to use vfork().

I'd happily take an implementation for libc of posix_spawn* that used fork() for now so we have it ready for vfork() in future and people can use it.

erkinalp commented 6 years ago

The problem is we do not have COW pages on Z80 and 6502, each fork is a complete time-consuming copy of previous process. spawnve could be implemented as a new process handle + empty memory block. The default shell could be modified to use spawn instead of fork for background (ampersand) process invocation, saving time. It will not work for foreground incovation because of terminal semantics.

EtchedPixels commented 6 years ago

Once we get a vfork() it won't copy. See the documentation for vfork on classic unix

erkinalp commented 1 year ago

A bit late, but would this be level 1, 2 or 3?

EtchedPixels commented 1 year ago

It's kind of irrelevant at this point as there is no use case and nobody needs it or has bothered to provide an implementation in the past 5 years nor anything that needs it.

The 8bit ports can't support it for various architectural reasons, the 68K copies only a few Kb and fast so it's mostly a non-issue and the ESP8266 and modern small risc chips fork /bin/sh in almost no time as it's a mere 32K which for a modern fast risc chip doesn't take any time

bscottm commented 1 year ago

@erkinalp: vfork() was a Berkeley-ism because older Unixen did a full process copy in fork(). Given that fork() and vfork() were (and are) followed by an immediate exec(), vfork() made sense. Then someone discovered demand paging (again) and the need for vfork() disappeared.

erkinalp commented 1 year ago

@bscottm Yes, but the need for spawn() did not. There is a reason POSIX now has a posix_spawn() call.

bscottm commented 1 year ago

@erkinalp: Didn't say anything about spawn() [courtesy of Microsoft]. All spawn() does is package fork() and exec().

erkinalp commented 1 year ago

No, what I mean is definitely a posix_spawn() that does not fork under the hood, but rather create a fresh process descriptor in a manner similar to Windows NT's CreateProcess() and then exec() to it.

bscottm commented 1 year ago

@erkinalp: fork() is supposed to create a fresh process descriptor. Copy-on-write and demand paging make fork() more efficient, when possible. Neither 6502 and Z80 have memory management units, so copy-on-write isn't feasible. Whether spawn and its variants exec() depends on the return value from fork(). That doesn't preclude an implementation from optimizing, as it sounds like is happening in this case.

EtchedPixels commented 1 year ago

To be more accurate programs then got enormously bloated and vfork became relevant again.

In the Fuzix case the only cases vfork looks useful are flat systems like 68K as it avoids a data copy on fork and switch, but nothing we have that forks copies much data (riscv and ns32k are a bit worse as the toolchains don't generate split code/data relocatable binaries- but riscv is fast and ns32k is more a tool chain problem)

So no use case, and no use case means not used means buggy