aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--process.c8
2 files changed, 19 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 5d7b694049..d4e1c38cd4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Wed Sep 3 12:05:17 2014 Tanaka Akira <akr@fsij.org>
+
+ * process.c (retry_fork_async_signal_safe): Use vfork() if available.
+ vfork() is still faster than fork() especially when the parent
+ process uses big memory.
+
+ ruby -rbenchmark -e 'a = "a" * 1_000_000_000; puts Benchmark.measure { system("true") }'
+ fork: 0.000000 0.010000 0.010000 ( 0.014968)
+ vfork: 0.000000 0.000000 0.000000 ( 0.000912)
+ on Debian sid.
+
Wed Sep 3 11:33:08 2014 SHIBATA Hiroshi <shibata.hiroshi@gmail.com>
* test/openssl/test_pkey_rsa.rb (OpenSSL#test_sign_verify_memory_leak):
diff --git a/process.c b/process.c
index 89f829c846..503e73923d 100644
--- a/process.c
+++ b/process.c
@@ -50,6 +50,9 @@
#ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h>
#endif
+#ifdef HAVE_VFORK_H
+# include <vfork.h>
+#endif
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
@@ -3291,7 +3294,11 @@ retry_fork_async_signal_safe(int *status, int *ep,
while (1) {
prefork();
+#ifdef HAVE_WORKING_VFORK
+ pid = vfork();
+#else
pid = fork();
+#endif
if (pid == 0) {/* fork succeed, child process */
int ret;
forked_child = 1;
@@ -3305,6 +3312,7 @@ retry_fork_async_signal_safe(int *status, int *ep,
_exit(127);
#endif
}
+ forked_child = 0; /* for vfork(). */
if (0 < pid) /* fork succeed, parent process */
return pid;
/* fork failed */