3 ms·
> Fil-C's pollchecks also support stop-the-world (via the FILC_THREAD_STATE_STOP_REQUESTED bit). This is used for: > - Implementing fork(2), which needs all
by cryptonector 1y ago
> Fil-C's pollchecks also support stop-the-world (via the FILC_THREAD_STATE_STOP_REQUESTED bit). This is used for:
> - Implementing fork(2), which needs all threads to stop at a known-good point before the fork child jettisons them.
Makes me wonder how it handles `vfork()`, but I think it needs just a safepoint and no stop-the-world since, after all, the child side of `vfork()` is executing in the same address space as the parent (until exec-or-exit), so it's as though it's the same thread as in the parent (which is stopped waiting for the child to exec-or-exit). All the more reasons that `fork()` is evil and `vfork()` much better.
- foota 1y agoI was looking at https://fil-c.org/programs_that_work https://fil-c.org/programs_that_work and saw "dash 0.5.12. One tiny change: use fork(2) instead of vfork(2).", so maybe it doesn't :)
- pizlonator 1y agoI don't support vfork(2) right now, only fork(2). I have some super crazy ideas about how to make vfork(2) work, but I don't particularly like any of them. I'll implement it if I find some situation where vfork(2) is strongly required (so far I haven't found even one such case). The closest is that I've found cases where I have to add the CLOEXEC pipe trick to do error handling the fork(2) way rather than the vfork(2) way.
- cryptonector 1y agoRemember that the child side of `vfork(2)` can only do async-signal-safe things as `vfork(2)` is documented, and it's really as if it is executing in the same thread as the parent (down to thread-locals, I do believe), so really, `vfork(2)` shouldn't really be all that special for Fil-C! You might want to try it. As u/foota notes, it's important. The point of `vfork(2)` is that it's _fast_. https://news.ycombinator.com/item?id=30502392 https://news.ycombinator.com/item?id=30502392
- pizlonator 1y ago> Remember that the child side of `vfork(2)` can only do async-signal-safe things as `vfork(2)` is documented And if it does anything that isn't async-signal-safe, then all bets are off. So, the Fil-C implementation of vfork(2) would have to have some way of checking (either statically or dynamically) that nothing async-signal-unsafe happens. That's the hard bit. That's why I think that implementing it is crazy. I'd have to have so many checks in so many weird places! > The point of `vfork(2)` is that it's _fast_ Yup. That's the reason to have it. But I haven't yet found a situation where a program I want to run is slow because I don't have vfork(2). The closest thing is that bash is visibly slower in Fil-C due to forking, but bash always uses fork(2) anyway - so in that case what I need to do is make my fork(2) impl faster, not implement vfork(2).
- cryptonector 1y ago> And if it does anything that isn't async-signal-safe, then all bets are off. > So, the Fil-C implementation of vfork(2) would have to have some way of checking (either statically or dynamically) that nothing async-signal-unsafe happens. That's the hard bit. That's why I think that implementing it is crazy. Not really. See, Fil-C already makes those things that would not be safe be safe except returning from the caller of `vfork(2)`. Treat the child as if it's the same thread as in the parent and let it do whatever it would do. Well, I guess the biggest issue is that you'd have to deal with how to communicate between the child and the GC thread, if you have to. One option is to just not allow the GC to run while a child of `vfork(2)` hasn't exec'ed-or-exit'ed. > > The point of `vfork(2)` is that it's _fast_ > Yup. That's the reason to have it. But I haven't yet found a situation where a program I want to run is slow because I don't have vfork(2). The closest thing is that bash is visibly slower in Fil-C due to forking, but bash always uses fork(2) anyway - so in that case what I need to do is make my fork(2) impl faster, not implement vfork(2). Typically it's programs with large RSS that need it, so things like JVMs, which probably wouldn't run under Fil-C.
- pizlonator 1y agoSimple example that breaks the world: void foo(void) { vfork(); } In this case, the vfork child is returning. Eventually it'll exit. In the meantime, it's clobbered the vfork parent's stack. Kaboom
- kmavm 1y agoHi Fil! Congrats on all the amazing progress on Fil-C. We needed to port all the user-level fork(2) calls to vfork(2) when working on uCLinux, a port of Linux to MMU-less microcontrollers[1]. It used to be that paging MMUs were kinda expensive (those TLBs! so much associativity!!!), and the CPU on your printer/ethernet card/etc. might not have that much grit. Nowadays not so much. Still. A hard-and-fast use for vfork(2), as requested perhaps. [1] http://www.ibiblio.org/lou/old/ViewStation/ http://www.ibiblio.org/lou/old/ViewStation/
- pizlonator 1y agoIt'll be a while before Fil-C is appropriate for use in MMU-less microcontrollers.