Commit 60cfe25e authored by Tom Lane's avatar Tom Lane

Adjust spawn_process() to avoid unnecessary overhead processes: we can

just exec instead of creating a subprocess.  This reduces process usage
from four processes per parallel test to two.  I have no idea whether
a comparable optimization is possible or useful in the Windows port.
parent 87c3129e
<!-- $PostgreSQL: pgsql/doc/src/sgml/regress.sgml,v 1.53 2006/07/19 02:37:00 tgl Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/regress.sgml,v 1.54 2006/07/19 17:02:59 tgl Exp $ -->
<chapter id="regress"> <chapter id="regress">
<title id="regress-title">Regression Tests</title> <title id="regress-title">Regression Tests</title>
...@@ -96,11 +96,10 @@ gmake check ...@@ -96,11 +96,10 @@ gmake check
<para> <para>
The parallel regression test starts quite a few processes under your The parallel regression test starts quite a few processes under your
user ID. Presently, the maximum concurrency is twenty parallel test user ID. Presently, the maximum concurrency is twenty parallel test
scripts, which means sixty processes: there's a server process, a scripts, which means forty processes: there's a server process and a
<application>psql</>, and usually a shell parent process for the <application>psql</> process for each test script.
<application>psql</> for each test script.
So if your system enforces a per-user limit on the number of processes, So if your system enforces a per-user limit on the number of processes,
make sure this limit is at least seventy-five or so, else you may get make sure this limit is at least fifty or so, else you may get
random-seeming failures in the parallel test. If you are not in random-seeming failures in the parallel test. If you are not in
a position to raise the limit, you can cut down the degree of parallelism a position to raise the limit, you can cut down the degree of parallelism
by setting the <literal>MAX_CONNECTIONS</> parameter. For example, by setting the <literal>MAX_CONNECTIONS</> parameter. For example,
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
# Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group # Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California # Portions Copyright (c) 1994, Regents of the University of California
# #
# $PostgreSQL: pgsql/src/test/regress/GNUmakefile,v 1.59 2006/07/19 04:02:31 tgl Exp $ # $PostgreSQL: pgsql/src/test/regress/GNUmakefile,v 1.60 2006/07/19 17:02:59 tgl Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
...@@ -39,7 +39,8 @@ EXTRADEFS = '-DPGBINDIR="$(bindir)"' \ ...@@ -39,7 +39,8 @@ EXTRADEFS = '-DPGBINDIR="$(bindir)"' \
'-DLIBDIR="$(libdir)"' \ '-DLIBDIR="$(libdir)"' \
'-DPGSHAREDIR="$(datadir)"' \ '-DPGSHAREDIR="$(datadir)"' \
'-DHOST_TUPLE="$(host_tuple)"' \ '-DHOST_TUPLE="$(host_tuple)"' \
'-DMAKEPROG="$(MAKE)"' '-DMAKEPROG="$(MAKE)"' \
'-DSHELLPROG="$(SHELL)"'
## ##
## Prepare for tests ## Prepare for tests
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/test/regress/pg_regress.c,v 1.4 2006/07/19 16:23:17 tgl Exp $ * $PostgreSQL: pgsql/src/test/regress/pg_regress.c,v 1.5 2006/07/19 17:02:59 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -60,6 +60,7 @@ static char *libdir = LIBDIR; ...@@ -60,6 +60,7 @@ static char *libdir = LIBDIR;
static char *datadir = PGSHAREDIR; static char *datadir = PGSHAREDIR;
static char *host_platform = HOST_TUPLE; static char *host_platform = HOST_TUPLE;
static char *makeprog = MAKEPROG; static char *makeprog = MAKEPROG;
static char *shellprog = SHELLPROG;
/* currently we can use the same diff switches on all platforms */ /* currently we can use the same diff switches on all platforms */
static const char *basic_diff_opts = "-w"; static const char *basic_diff_opts = "-w";
...@@ -630,8 +631,20 @@ spawn_process(const char *cmdline) ...@@ -630,8 +631,20 @@ spawn_process(const char *cmdline)
} }
if (pid == 0) if (pid == 0)
{ {
/* In child */ /*
exit(system(cmdline) ? 1 : 0); * In child
*
* Instead of using system(), exec the shell directly, and tell it
* to "exec" the command too. This saves two useless processes
* per parallel test case.
*/
char *cmdline2 = malloc(strlen(cmdline) + 6);
sprintf(cmdline2, "exec %s", cmdline);
execl(shellprog, shellprog, "-c", cmdline2, NULL);
fprintf(stderr, _("%s: could not exec \"%s\": %s\n"),
progname, shellprog, strerror(errno));
exit(1); /* not exit_nicely here... */
} }
/* in parent */ /* in parent */
return pid; return pid;
...@@ -648,7 +661,7 @@ spawn_process(const char *cmdline) ...@@ -648,7 +661,7 @@ spawn_process(const char *cmdline)
if (!CreateProcess(NULL, cmdline2, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) if (!CreateProcess(NULL, cmdline2, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{ {
fprintf(stderr, _("failed to start process for \"%s\": %lu\n"), fprintf(stderr, _("could not start process for \"%s\": %lu\n"),
cmdline2, GetLastError()); cmdline2, GetLastError());
exit_nicely(2); exit_nicely(2);
} }
...@@ -684,7 +697,7 @@ psql_start_test(const char *testname) ...@@ -684,7 +697,7 @@ psql_start_test(const char *testname)
if (pid == INVALID_PID) if (pid == INVALID_PID)
{ {
fprintf(stderr, _("failed to start process for test %s\n"), fprintf(stderr, _("could not start process for test %s\n"),
testname); testname);
exit_nicely(2); exit_nicely(2);
} }
...@@ -918,7 +931,7 @@ wait_for_tests(PID_TYPE *pids, int num_tests) ...@@ -918,7 +931,7 @@ wait_for_tests(PID_TYPE *pids, int num_tests)
if (p == -1) if (p == -1)
{ {
fprintf(stderr, _("failed to wait(): %s\n"), strerror(errno)); fprintf(stderr, _("could not wait(): %s\n"), strerror(errno));
exit_nicely(2); exit_nicely(2);
} }
for (i=0; i < num_tests; i++) for (i=0; i < num_tests; i++)
...@@ -938,7 +951,7 @@ wait_for_tests(PID_TYPE *pids, int num_tests) ...@@ -938,7 +951,7 @@ wait_for_tests(PID_TYPE *pids, int num_tests)
r = WaitForMultipleObjects(num_tests, pids, TRUE, INFINITE); r = WaitForMultipleObjects(num_tests, pids, TRUE, INFINITE);
if (r != WAIT_OBJECT_0) if (r != WAIT_OBJECT_0)
{ {
fprintf(stderr, _("failed to wait for commands to finish: %lu\n"), fprintf(stderr, _("could not wait for commands to finish: %lu\n"),
GetLastError()); GetLastError());
exit_nicely(2); exit_nicely(2);
} }
...@@ -1228,7 +1241,7 @@ main(int argc, char *argv[]) ...@@ -1228,7 +1241,7 @@ main(int argc, char *argv[])
int c; int c;
int i; int i;
int option_index; int option_index;
char buf[MAXPGPATH]; char buf[MAXPGPATH * 4];
static struct option long_options[] = { static struct option long_options[] = {
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
...@@ -1431,14 +1444,6 @@ main(int argc, char *argv[]) ...@@ -1431,14 +1444,6 @@ main(int argc, char *argv[])
exit_nicely(2); exit_nicely(2);
} }
/*
* XXX Note that because we use system() to launch the subprocess,
* the returned postmaster_pid is not really the PID of the
* postmaster itself; on most systems it'll be the PID of a parent
* shell process. This is OK for the limited purposes we currently
* use postmaster_pid for, but beware!
*/
/* /*
* Wait till postmaster is able to accept connections (normally only * Wait till postmaster is able to accept connections (normally only
* a second or so, but Cygwin is reportedly *much* slower). Don't * a second or so, but Cygwin is reportedly *much* slower). Don't
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment