[m-rev.] for review: more efficient parallel mmc --make
Peter Wang
novalazy at gmail.com
Thu Jul 30 14:27:24 AEST 2009
On 2009-07-29, Julien Fischer <juliensf at csse.unimelb.edu.au> wrote:
>
> That looks okay. Please check that it works (or is at least
> properly disabled) on systems other than Linux before committing.
Good old Mac OS X, never fails to underwhelm. It supports named POSIX
semaphores but not *unnamed* semaphores. So I changed the code to use pthread
mutexes instead, and somehow thought that it worked. Then after committing
it I found out that it doesn't support process-shared pthread mutexes
either (I probably had tested the wrong Mercury compiler).
System V semaphores (different again) *do* work, so I've made it use those on
Darwin. They also work on Linux, and if they work on Cygwin as well I might
just use them everywhere to reduce the conditional code. Annoyingly that's
what I had implemented in the first place.
Is there a Cygwin machine I can log into?
Here are the changes since the reviewed patch:
diff --git a/Mmake.common.in b/Mmake.common.in
index aaca235..acd0486 100644
--- a/Mmake.common.in
+++ b/Mmake.common.in
@@ -214,7 +214,7 @@ PERL=@PERL@
MATH_LIB=@MATH_LIB@
# More libraries to link
-SEMAPHORE_LIBRARY=@SEMAPHORE_LIBRARY@
+THREAD_LIBS=@THREAD_LIBS@
SOCKET_LIBRARY=@SOCKET_LIBRARY@
NSL_LIBRARY=@NSL_LIBRARY@
DL_LIBRARY=@DL_LIBRARY@
diff --git a/compiler/Mmakefile b/compiler/Mmakefile
index 62a0d60..7cc5156 100644
--- a/compiler/Mmakefile
+++ b/compiler/Mmakefile
@@ -68,7 +68,7 @@ MCFLAGS += --flags COMP_FLAGS $(CONFIG_OVERRIDE)
MLOBJS := ../main.$O \
../trace/lib$(EVENTSPEC_LIB_NAME).$A \
$(MLOBJS)
-MLLIBS += $(SEMAPHORE_LIBRARY)
+MLLIBS += $(THREAD_LIBS)
ALL_MLLIBS = $(MLLIBS) $(EXTRA_MLLIBS) $(GCC_BACKEND_LIBS)
MLFLAGS += --no-main --shared
C2INITARGS += $(MDBCOMP_DIR)/$(MDBCOMP_LIB_NAME).init
diff --git a/compiler/make.util.m b/compiler/make.util.m
index bc883d0..5c29bee 100644
--- a/compiler/make.util.m
+++ b/compiler/make.util.m
@@ -520,16 +520,29 @@ typedef struct MC_JobCtl MC_JobCtl;
:- pragma foreign_decl("C", local,
"
-#if defined(MR_HAVE_SEMAPHORE_H) && defined(MR_HAVE_SYS_MMAN_H)
- #include <semaphore.h>
+#ifdef MR_HAVE_SYS_MMAN_H
#include <sys/mman.h>
/* Just in case. */
#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
#define MAP_ANONYMOUS MAP_ANON
#endif
+#endif
+
+#ifdef MAP_ANONYMOUS
+ /*
+ ** Darwin 5.x doesn't implement unnamed POSIX semaphores nor process-shared
+ ** POSIX mutexes; the functions fail when you try to create them.
+ ** System V semaphores do work however.
+ */
+ #if !defined(__APPLE__) && defined(MR_HAVE_PTHREAD_H)
+ #include <pthread.h>
+
+ #define MC_HAVE_JOBCTL_IPC 1
+ #elif defined(MR_HAVE_SYS_SEM_H)
+ #include <sys/sem.h>
- #ifdef MAP_ANONYMOUS
+ #define MC_USE_SYSV_SEMAPHORE 1
#define MC_HAVE_JOBCTL_IPC 1
#endif
#endif
@@ -548,10 +561,14 @@ enum MC_TaskStatus {
/* This structure is placed in shared memory. */
struct MC_JobCtl {
/* Static data. */
- sem_t jc_sem;
MR_Integer jc_total_tasks;
- /* Dynamic data, protected with a semaphore. */
+ /* Dynamic data. The mutex protects the rest. */
+ #ifdef MC_USE_SYSV_SEMAPHORE
+ int jc_semid;
+ #else
+ pthread_mutex_t jc_mutex;
+ #endif
MR_bool jc_abort;
MC_TaskStatus jc_tasks[MR_VARIABLE_SIZED];
};
@@ -572,29 +589,66 @@ static void MC_unlock_job_ctl(MC_JobCtl *job_ctl);
static MC_JobCtl *
MC_create_job_ctl(MR_Integer total_tasks)
{
- sem_t sem;
- int shmid;
- MC_JobCtl *job_ctl;
- MR_Integer i;
-
- shmid = -1;
+ size_t size;
+ MC_JobCtl *job_ctl;
+ MR_Integer i;
- /* Create semaphore. */
- if (sem_init(&sem, 1, 1) != 0) {
- perror(""MC_create_job_ctl: sem_init"");
- return NULL;
- }
+ size = MC_JOB_CTL_SIZE(total_tasks);
/* Create the shared memory segment. */
- job_ctl = mmap(NULL, MC_JOB_CTL_SIZE(total_tasks), PROT_READ | PROT_WRITE,
+ job_ctl = mmap(NULL, size, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_SHARED, -1, 0);
if (job_ctl == (void *) -1) {
perror(""MC_create_job_ctl: mmap"");
- sem_destroy(&sem);
return NULL;
}
- job_ctl->jc_sem = sem;
+#ifdef MC_USE_SYSV_SEMAPHORE
+ {
+ struct sembuf sb;
+
+ job_ctl->jc_semid = semget(IPC_PRIVATE, 1, 0600);
+ if (job_ctl->jc_semid == -1) {
+ perror(""MC_create_sem: semget"");
+ munmap(job_ctl, size);
+ return NULL;
+ }
+
+ sb.sem_num = 0;
+ sb.sem_op = 1;
+ sb.sem_flg = 0;
+ if (semop(job_ctl->jc_semid, &sb, 1) == -1) {
+ perror(""MC_create_sem: semop"");
+ semctl(job_ctl->jc_semid, 0, IPC_RMID);
+ munmap(job_ctl, size);
+ return NULL;
+ }
+ }
+#else
+ {
+ pthread_mutexattr_t mutex_attr;
+
+ pthread_mutexattr_init(&mutex_attr);
+ if (pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED)
+ != 0)
+ {
+ perror(""MC_create_job_ctl: pthread_mutexattr_setpshared"");
+ pthread_mutexattr_destroy(&mutex_attr);
+ munmap(job_ctl, size);
+ return NULL;
+ }
+
+ if (pthread_mutex_init(&job_ctl->jc_mutex, &mutex_attr) != 0) {
+ perror(""MC_create_job_ctl: sem_init"");
+ pthread_mutexattr_destroy(&mutex_attr);
+ munmap(job_ctl, size);
+ return NULL;
+ }
+
+ pthread_mutexattr_destroy(&mutex_attr);
+ }
+#endif
+
job_ctl->jc_total_tasks = total_tasks;
job_ctl->jc_abort = MR_FALSE;
for (i = 0; i < total_tasks; i++) {
@@ -607,13 +661,35 @@ MC_create_job_ctl(MR_Integer total_tasks)
static void
MC_lock_job_ctl(MC_JobCtl *job_ctl)
{
- sem_wait(&job_ctl->jc_sem);
+#ifdef MC_USE_SYSV_SEMAPHORE
+ struct sembuf sb;
+
+ sb.sem_num = 0;
+ sb.sem_op = -1;
+ sb.sem_flg = 0;
+ if (semop(job_ctl->jc_semid, &sb, 1) == -1) {
+ perror(""MC_lock_job_ctl: semop"");
+ }
+#else
+ pthread_mutex_lock(&job_ctl->jc_mutex);
+#endif
}
static void
MC_unlock_job_ctl(MC_JobCtl *job_ctl)
{
- sem_post(&job_ctl->jc_sem);
+#ifdef MC_USE_SYSV_SEMAPHORE
+ struct sembuf sb;
+
+ sb.sem_num = 0;
+ sb.sem_op = 1;
+ sb.sem_flg = 0;
+ if (semop(job_ctl->jc_semid, &sb, 1) == -1) {
+ perror(""MC_unlock_job_ctl: semop"");
+ }
+#else
+ pthread_mutex_unlock(&job_ctl->jc_mutex);
+#endif
}
#endif /* MC_HAVE_JOBCTL_IPC */
@@ -638,8 +714,6 @@ have_job_ctl_ipc :-
#endif
").
- % The job control structure should really be unique that's too annoying.
- %
:- pred create_job_ctl(int::in, maybe(job_ctl)::out, io::di, io::uo) is det.
:- pragma foreign_proc("C",
@@ -670,7 +744,12 @@ have_job_ctl_ipc :-
may_not_duplicate],
"
#ifdef MC_HAVE_JOBCTL_IPC
- sem_destroy(&JobCtl->jc_sem);
+ #ifdef MC_USE_SYSV_SEMAPHORE
+ semctl(JobCtl->jc_semid, 0, IPC_RMID);
+ #else
+ pthread_mutex_destroy(&JobCtl->jc_mutex);
+ #endif
+
munmap(JobCtl, MC_JOB_CTL_SIZE(JobCtl->jc_total_tasks));
#endif
IO = IO0;
diff --git a/configure.in b/configure.in
index b18d87e..d05fcef 100644
--- a/configure.in
+++ b/configure.in
@@ -1096,7 +1096,7 @@ MERCURY_CHECK_FOR_HEADERS( \
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 spawn.h fenv.h sys/mman.h)
+ semaphore.h pthread.h time.h spawn.h fenv.h sys/mman.h sys/sem.h)
if test "$MR_HAVE_GETOPT_H" = 1; then
GETOPT_H_AVAILABLE=yes
@@ -4379,15 +4379,6 @@ MERCURY_CHECK_FOR_IEEE_FUNC(isinff)
#-----------------------------------------------------------------------------#
#
-# Check whether POSIX semaphores requires -lrt
-#
-
-AC_CHECK_LIB(rt, sem_init, SEMAPHORE_LIBRARY=-lrt, SEMAPHORE_LIBRARY="")
-
-AC_SUBST(SEMAPHORE_LIBRARY)
-
-#-----------------------------------------------------------------------------#
-#
# Check whether sockets work (we need them for the external debugger)
#
diff --git a/runtime/mercury_conf.h.in b/runtime/mercury_conf.h.in
index 987e84c..99fee3d 100644
--- a/runtime/mercury_conf.h.in
+++ b/runtime/mercury_conf.h.in
@@ -135,6 +135,7 @@
** MR_HAVE_SPAWN_H we have <spawn.h>
** MR_HAVE_FENV_H we have <fenv.h>
** MR_HAVE_SYS_MMAN_H we have <sys/mman.h>
+** MR_HAVE_SYS_SEM_H we have <sys/sem.h>
*/
#undef MR_HAVE_SYS_SIGINFO_H
#undef MR_HAVE_SYS_SIGNAL_H
@@ -163,6 +164,7 @@
#undef MR_HAVE_SPAWN_H
#undef MR_HAVE_FENV_H
#undef MR_HAVE_SYS_MMAN_H
+#undef MR_HAVE_SYS_SEM_H
/*
** MR_HAVE_POSIX_TIMES is defined if we have the POSIX
--------------------------------------------------------------------------
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