This is experimental clone() (vs. fork()) patch for mpm-itk apache 2.2. Really I see no perfomance benefits, but only little RAM. But using CLONE_VFORK must relax cheduling in theory. Primary - for experiments with LXC. (c) Denis Kaganovich, Licensed under the same terms as the rest of Apache (or Anarchy license). In this version I remove vfork by default die to segfaults. --- a/server/mpm/itk/itk.c 2012-03-03 16:43:55.000000000 +0300 +++ b/server/mpm/itk/itk.c 2012-03-06 11:49:16.000000000 +0300 @@ -100,6 +100,19 @@ #define HARD_THREAD_LIMIT 1 #endif +#ifdef __linux__ +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,49) && defined(CLONE_FS) +#define ITK_USE_CLONE 1 +static int clone_flags1 = 0, clone_flags2 = 0; +#else +#define ITK_USE_CLONE 0 +#endif +#else +#define ITK_USE_CLONE 0 +#endif + /* config globals */ static apr_proc_mutex_t *accept_mutex; @@ -751,7 +764,11 @@ static void child_main(int child_num_arg */ { +#if ITK_USE_CLONE + pid_t pid = syscall(SYS_clone, clone_flags1, 0, NULL, NULL), child_pid; +#else pid_t pid = fork(), child_pid; +#endif int status; switch (pid) { case -1: @@ -840,6 +857,8 @@ static int make_child(server_rec *s, int #ifdef _OSD_POSIX /* BS2000 requires a "special" version of fork() before a setuid() call */ if ((pid = os_fork(ap_unixd_config.user_name)) == -1) { +#elif ITK_USE_CLONE + if ((pid = syscall(SYS_clone, clone_flags2, 0, NULL, NULL)) == -1) { #else if ((pid = fork()) == -1) { #endif @@ -1404,6 +1423,10 @@ static int itk_pre_config(apr_pool_t *p, server_limit = DEFAULT_SERVER_LIMIT; ap_daemons_limit = server_limit; ap_extended_status = 0; +#if ITK_USE_CLONE + clone_flags1 = SIGCHLD; + clone_flags2 = SIGCHLD | CLONE_FS; +#endif return OK; } @@ -1767,6 +1790,19 @@ static const char *set_chroot(cmd_parms return NULL; } +#if ITK_USE_CLONE +static const char *set_clone_flags(cmd_parms *cmd, void *dummy, const char *flags1, const char *flags2) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) + return err; + + clone_flags1 = (SIGCHLD) ^ atoi(flags1); + clone_flags2 = (SIGCHLD | CLONE_FS) ^ (flags2 ? atoi(flags2) : 0); + return NULL; +} +#endif + static const command_rec itk_cmds[] = { LISTEN_COMMANDS, AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF, @@ -1789,6 +1825,10 @@ AP_INIT_TAKE1("MaxClientsVHost", set_max "Maximum number of children alive at the same time for this virtual host."), AP_INIT_TAKE1("NiceValue", set_nice_value, NULL, RSRC_CONF|ACCESS_CONF, "Set nice value for the given vhost, from -20 (highest priority) to 19 (lowest priority)."), +#if ITK_USE_CLONE +AP_INIT_TAKE12("CloneFlags", set_clone_flags, NULL, RSRC_CONF, + "XOR to default (SIGCHLD, SIGCHLD|CLONE_FS) clone flags. See /usr/include/{linux,bits}/sched.h or 'man 2 clone'"), +#endif AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND, { NULL } };