Make fork() go 30% faster

This change makes fork() go nearly as fast as sys_fork() on UNIX. As for
Windows this change shaves about 4-5ms off fork() + wait() latency. This
is accomplished by using WriteProcessMemory() from the parent process to
setup the address space of a suspended process; it is better than a pipe
This commit is contained in:
Justine Tunney 2025-01-01 04:59:38 -08:00
parent 98c5847727
commit 0b3c81dd4e
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
44 changed files with 769 additions and 649 deletions

View file

@ -21,6 +21,7 @@
#include "libc/calls/struct/sigaction.h"
#include "libc/calls/struct/sigset.h"
#include "libc/calls/struct/timespec.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/log/check.h"
@ -32,6 +33,7 @@
#include "libc/sysv/consts/msync.h"
#include "libc/sysv/consts/prot.h"
#include "libc/sysv/consts/sig.h"
#include "libc/testlib/benchmark.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/subprocess.h"
#include "libc/testlib/testlib.h"
@ -150,6 +152,31 @@ void ForkInSerial(void) {
ASSERT_EQ(0, WEXITSTATUS(ws));
}
BENCH(fork, bench) {
EZBENCH2("fork a", donothing, ForkInSerial());
void VforkInSerial(void) {
int pid, ws;
ASSERT_NE(-1, (pid = vfork()));
if (!pid)
_Exit(0);
ASSERT_NE(-1, waitpid(pid, &ws, 0));
ASSERT_TRUE(WIFEXITED(ws));
ASSERT_EQ(0, WEXITSTATUS(ws));
}
void SysForkInSerial(void) {
int pid, ws;
ASSERT_NE(-1, (pid = sys_fork()));
if (!pid)
_Exit(0);
ASSERT_NE(-1, waitpid(pid, &ws, 0));
ASSERT_TRUE(WIFEXITED(ws));
ASSERT_EQ(0, WEXITSTATUS(ws));
}
TEST(fork, bench) {
VforkInSerial();
BENCHMARK(10, 1, VforkInSerial());
if (!IsWindows())
BENCHMARK(10, 1, SysForkInSerial());
ForkInSerial();
BENCHMARK(10, 1, ForkInSerial());
}