summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/forkfd/forkfd_freebsd.c
Commit message (Collapse)AuthorAgeFilesLines
* forkfd: implement vfork(2)-like support on LinuxThiago Macieira2022-07-161-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | fork() works by implementing Copy-On-Write for all pages that either the parent or the child process write to. So if the parent process continues running while the child is between fork(2) and execve(2), then it will keep causing page faults and requiring the OS to duplicate those pages, which may be expensive (page table updates, TLB flushes, etc.). This problem is aggravated if the parent process is multithreaded, as the simple act of running in the parent will cause those threads' stacks to cause page faults. The BSD solution for that was vfork(), which has two differences in behavior: (1) it blocks the parent from running and (2) it shares memory with it. But it's always been tricky, so POSIX.1-2001 deprecated it and 2008 removed its definition completely. Still, it is available somewhat widely, and on Linux that can be achieved with clone(2) and the CLONE_VFORK and CLONE_VM flags, for those two behaviors respectively. Because of (2), we can't return from the forkfd() function in the child (as that would trash the stack in the parent process), so to implement this functionality vforkfd() adds a callback of the same signature as glibc's clone(2) wrapper (something that hadn't occurred to me when we attempted to use CLONE_VFORK last time). On Linux, (1) is no problem, as clone(2) has native forkfd support. But on other OSes, forkfd() requires the parent to run before the child execve()s, in order to save the child PID in the list of children we're going to handle SIGCHLD for in a non-racy way. Investigating if it is possible to use vfork() anyway is left as an exercise for the reader. Matching OpenDCDiag pull request: https://github.com/opendcdiag/opendcdiag/pull/94 Pick-to: 6.4 Fixes: QTBUG-104493 Change-Id: Id0fb9ab0089845ee8843fffd16fa63c7c6f7dd1c Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Milian Wolff <milian.wolff@kdab.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* forkfd: introduce forkfd_wait4() that takes optionsThiago Macieira2020-03-251-7/+15
| | | | | | | | | | | | | | | | | | "wait4" because it looks like the wait4() BSD function, which has the signature: pid_t wait4(pid_t pid, int *wstatus, int options, struct rusage *rusage); And because ours also has 4 parameters. Having options is important anyway. I might want to add some more later, but we can't really support them with the fall back implementation (in fact, we don't honor WNOHANG in the fall back implementation either). Change-Id: I4e559af2a9a1455ab770fffd15f5858bb357e15b Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
* forkfd: move the FreeBSD system implementation to a separate fileThiago Macieira2019-08-201-0/+101
Simplifies the code a bit and will be helpful when I add the Linux equivalent. Change-Id: Iec9c051acd73484c8d94fffd15b99879dc269db9 Reviewed-by: Lars Knoll <lars.knoll@qt.io>