[m-rev.] for review: use posix_spawn() instead of system() on MT grades
Peter Wang
wangp at students.csse.unimelb.edu.au
Thu Jul 12 15:39:27 AEST 2007
Estimated hours taken: 3
Branches: main
There are some problems with calling system() in multi-threaded programs on the
Linux machines I have tested parallel mmc --make on. On glibc 2.3.x machines
there have been assertion failures while launching programs. On a glibc 2.5.x
machine the parent process got into infinite loops.
This patch replaces system() in multithreaded grades by posix_spawn(), which
doesn't seem to suffer the same problems.
configure.in:
runtime/mercury_conf.h.in:
Check for availability of <spawn.h>, posix_spawn() and the environ
global variable.
library/io.m:
Use posix_spawn() to implement io.call_system_code in multi-threaded
C grades if available.
Index: configure.in
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/configure.in,v
retrieving revision 1.493
diff -u -r1.493 configure.in
--- configure.in 19 Jun 2007 03:12:46 -0000 1.493
+++ configure.in 12 Jul 2007 05:19:36 -0000
@@ -963,7 +963,7 @@
getpid setpgid fork execlp wait kill \
grantpt unlockpt ptsname tcgetattr tcsetattr ioctl \
access sleep opendir readdir closedir mkdir symlink readlink \
- gettimeofday setenv putenv _putenv
+ gettimeofday setenv putenv _putenv posix_spawn
#-----------------------------------------------------------------------------#
MERCURY_CHECK_FOR_HEADERS( \
@@ -971,7 +971,7 @@
asm/sigcontext.h sys/param.h sys/time.h sys/times.h \
sys/types.h sys/stat.h fcntl.h termios.h sys/ioctl.h \
sys/stropts.h windows.h dirent.h getopt.h malloc.h \
- semaphore.h pthread.h time.h)
+ semaphore.h pthread.h time.h spawn.h)
if test "$MR_HAVE_GETOPT_H" = 1; then
GETOPT_H_AVAILABLE=yes
@@ -3983,6 +3983,30 @@
#-----------------------------------------------------------------------------#
#
+# Check for the environ global variable.
+#
+AC_MSG_CHECKING(for environ global variable)
+AC_CACHE_VAL(mercury_cv_have_environ,
+AC_TRY_LINK([
+ #include <unistd.h>
+
+ extern char **environ;
+],[
+ environ
+],[mercury_cv_have_environ=yes],[mercury_cv_have_environ=no]))
+
+#
+# figure out whether the test succeeded
+#
+if test "$mercury_cv_have_environ" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(MR_HAVE_ENVIRON)
+else
+ AC_MSG_RESULT(no)
+fi
+
+#-----------------------------------------------------------------------------#
+#
# Check for the WIN32 Sleep function
#
Index: library/io.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.394
diff -u -r1.394 io.m
--- library/io.m 22 Jun 2007 04:42:21 -0000 1.394
+++ library/io.m 12 Jul 2007 05:26:09 -0000
@@ -9004,12 +9004,67 @@
MR_update_io(IO0, IO);
").
+:- pragma foreign_decl("C", "
+
+#ifdef MR_HAVE_ENVIRON
+ #include <unistd.h>
+
+ /* The man page says that this should be declared by the user program. */
+ extern char **environ;
+#endif
+
+#ifdef MR_HAVE_SPAWN_H
+ #include <spawn.h>
+#endif
+").
+
:- pragma foreign_proc("C",
io.call_system_code(Command::in, Status::out, Msg::out,
IO0::di, IO::uo),
[will_not_call_mercury, promise_pure, tabled_for_io, thread_safe,
does_not_affect_liveness],
"
+ /*
+ ** In multithreaded grades, try to use posix_spawn() instead of system().
+ ** There were problems with threads and system() on Linux/glibc, probably
+ ** because system() uses fork().
+ */
+#if defined(MR_THREAD_SAFE) && defined(MR_HAVE_POSIX_SPAWN) && \
+ defined(MR_HAVE_ENVIRON)
+
+ char *argv[4];
+ pid_t pid;
+ int err;
+ int st;
+
+ argv[0] = ""sh"";
+ argv[1] = ""-c"";
+ argv[2] = Command;
+ argv[3] = NULL;
+
+ err = posix_spawn(&pid, ""/bin/sh"", NULL, NULL, argv,
+ (char * const) environ);
+ if (err != 0) {
+ /* Spawn failed. */
+ Status = 127;
+ ML_maybe_make_err_msg(MR_TRUE, errno,
+ ""error invoking system command: "", MR_PROC_LABEL, MR_TRUE, Msg);
+ } else {
+ /* Wait for the spawned process to exit. */
+ err = waitpid(pid, &st, 0);
+ if (err == -1) {
+ Status = 127;
+ ML_maybe_make_err_msg(MR_TRUE, errno,
+ ""error invoking system command: "", MR_PROC_LABEL, MR_TRUE,
+ Msg);
+ } else {
+ Status = st;
+ Msg = MR_make_string_const("""");
+ }
+ }
+
+#else /* !MR_THREAD_SAFE || !MR_HAVE_POSIX_SPAWN || !MR_HAVE_ENVIRON */
+
Status = system(Command);
if (Status == -1) {
/*
@@ -9023,6 +9078,9 @@
} else {
Msg = MR_make_string_const("""");
}
+
+#endif /* !MR_THREAD_SAFE || !MR_HAVE_POSIX_SPAWN || !MR_HAVE_ENVIRON */
+
MR_update_io(IO0, IO);
").
Index: runtime/mercury_conf.h.in
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_conf.h.in,v
retrieving revision 1.59
diff -u -r1.59 mercury_conf.h.in
--- runtime/mercury_conf.h.in 22 Dec 2006 08:31:18 -0000 1.59
+++ runtime/mercury_conf.h.in 12 Jul 2007 05:08:45 -0000
@@ -132,6 +132,7 @@
** MR_HAVE_SEMAPHORE_H we have <semaphore.h>
** MR_HAVE_PTHREAD_H we have <pthread.h>
** MR_HAVE_TIME_H we have <time.h>
+** MR_HAVE_SPAWN_H we have <spawn.h>
*/
#undef MR_HAVE_SYS_SIGINFO_H
#undef MR_HAVE_SYS_SIGNAL_H
@@ -157,6 +158,7 @@
#undef MR_HAVE_SEMAPHORE_H
#undef MR_HAVE_PTHREAD_H
#undef MR_HAVE_TIME_H
+#undef MR_HAVE_SPAWN_H
/*
** MR_HAVE_POSIX_TIMES is defined if we have the POSIX
@@ -165,6 +167,11 @@
#undef MR_HAVE_POSIX_TIMES
/*
+** MR_HAVE_ENVIRON is defined if we have the environ global variable.
+*/
+#undef MR_HAVE_ENVIRON
+
+/*
** The following macros are defined iff the corresponding type
** is available (in <stdint.h>, <inttypes.h>, or <sys/types.h>):
**
@@ -248,6 +255,7 @@
** MR_HAVE_SETENV we have the setenv() function.
** MR_HAVE_PUTENV we have the putenv() function.
** MR_HAVE__PUTENV we have the _putenv() function.
+** MR_HAVE_POSIX_SPAWN we have the posix_spawn() function.
*/
#undef MR_HAVE_GETPID
#undef MR_HAVE_SETPGID
@@ -307,6 +315,7 @@
#undef MR_HAVE_SETENV
#undef MR_HAVE_PUTENV
#undef MR_HAVE__PUTENV
+#undef MR_HAVE_POSIX_SPAWN
/*
** We use mprotect() and signals to catch stack and heap overflows.
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list