[m-rev.] for review: coroutining for parallel conjunctions

Peter Wang wangp at students.cs.mu.OZ.AU
Fri Jun 30 19:05:21 AEST 2006


By the way, is anyone using asm_fast.par.gc on saturn and earth?
Otherwise I'll change those installations to asm_jump.par.gc, which
don't suffer from the random errors (somehow related to gcc global
registers, GC and whether you link with pthreads statically or not
-- wtf?).


Estimated hours taken: 8
Branches: main

Add coroutining support for dependent parallel conjunctions in lowlevel
parallel grades.

library/par_builtin.m:
	Change definitions of synchronisation primitives so that waiting on a
	future causes the current context to be suspended.  Signalling a
	future causes all the contexts waiting on the future to be scheduled.

tests/par_conj/Mmakefile:
	Actually run dependent parallel conjunction tests since they should
	no longer deadlock.

tests/par_conj/*.exp:
	Add expected outputs for test cases which didn't have them.

tests/par_conj/*.m:
	Add calls to `io.flush_output'.  Without them there were some
	spurious failures (to be investigated later).


Index: library/par_builtin.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/par_builtin.m,v
retrieving revision 1.1
diff -u -r1.1 par_builtin.m
--- library/par_builtin.m	28 Jun 2006 04:46:19 -0000	1.1
+++ library/par_builtin.m	30 Jun 2006 06:13:38 -0000
@@ -11,8 +11,8 @@
 % Stability: low.
 
 % This file is automatically imported, as if via `use_module', into every
-% module in parallel grades.  It is intended for the builtin procedures that
-% the compiler generates implicit calls to when implementing parallel
+% module in lowlevel parallel grades.  It is intended for the builtin procedures
+% that the compiler generates implicit calls to when implementing parallel
 % conjunctions.
 %
 % This module is a private part of the Mercury implementation; user modules
@@ -55,27 +55,21 @@
 
 :- pragma foreign_decl("C",
 "
+    #include ""mercury_context.h""
+    #include ""mercury_thread.h""
+
     typedef struct MR_Future MR_Future;
 
 #ifdef MR_THREAD_SAFE
-# ifdef MR_HAVE_SEMAPHORE_H
-    /* POSIX 1003.1b semaphores available. */
-    #include <semaphore.h>
-
-    struct MR_Future {
-        sem_t   semaphore;
-        MR_Word value;
-    };
-# else /* !MR_HAVE_SEMAPHORE_H */
-    /* Use POSIX thread mutexes and condition variables. */
-    #include <pthread.h>
-
     struct MR_Future {
-        pthread_mutex_t mutex;
-        pthread_cond_t cond;
+        MercuryLock lock;
+            /* lock preventing concurrent accesses */
+        int signalled;
+            /* whether this future has been signalled yet */
+        MR_Context *suspended;
+            /* linked list of all the contexts blocked on this future */
         MR_Word value;
     };
-# endif /* !MR_HAVE_SEMAPHORE_H */
 #else /* !MR_THREAD_SAFE */
     struct MR_Future {
     };
@@ -92,37 +86,111 @@
     new_future(Future::uo),
     [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
 "
-#ifdef MR_THREAD_SAFE
-# ifdef MR_HAVE_SEMAPHORE_H
-    Future = MR_GC_NEW(MR_Future);
-    sem_init(&Future->semaphore, MR_NO, 0);
-    Future->value = 0;
-# else
-    Future = MR_GC_NEW(MR_Future);
-    pthread_mutex_init(&Future->mutex, NULL);
-    pthread_cond_init(&Future->cond, NULL);
+#if (!defined MR_HIGHLEVEL_CODE) && (defined MR_THREAD_SAFE)
+
+    MR_Word fut_addr;
+
+    MR_incr_hp(fut_addr, MR_round_up(sizeof(MR_Future), sizeof(MR_Word)));
+    Future = (MR_Future *) fut_addr;
+
+    pthread_mutex_init(&(Future->lock), MR_MUTEX_ATTR);
+
+    /*
+    ** The mutex needs to be destroyed when the future is garbage collected.
+    ** For efficiency we might want to ignore this altogether, e.g. on Linux
+    ** pthread_mutex_destroy() only checks that the mutex is unlocked.
+    */
+  #ifdef MR_CONSERVATIVE_GC
+    GC_REGISTER_FINALIZER(Future, MR_finalize_future, NULL, NULL, NULL);
+  #endif
+
+    Future->signalled = 0;
+    Future->suspended = NULL;
     Future->value = 0;
-# endif
+
+#else
+
+    MR_fatal_error(""internal error: par_builtin should only be used by ""
+        ""lowlevel parallel grades"");
+
+#endif
+").
+
+:- pragma foreign_decl("C", "
+#ifdef MR_CONSERVATIVE_GC
+    void MR_finalize_future(GC_PTR obj, GC_PTR cd);
+#endif
+").
+
+:- pragma foreign_code("C", "
+#ifdef MR_CONSERVATIVE_GC
+    void
+    MR_finalize_future(GC_PTR obj, GC_PTR cd)
+    {
+        MR_Future *fut = (MR_Future *) obj;
+
+      #ifdef MR_THREAD_SAFE
+        pthread_mutex_destroy(&(fut->lock));
+      #endif
+    }
 #endif
 ").
 
+    % Because par_builtin.wait has a local label, we may get
+    % C compilation errors if inlining leads to multiple copies
+    % of this code.
+    % 
+    % XXX get rid of this limitation at some stage.
+    %
+:- pragma no_inline(par_builtin.wait/2).
 :- pragma foreign_proc("C",
     wait(Future::in, Value::out),
     [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
 "
-#ifdef MR_THREAD_SAFE
-# ifdef MR_HAVE_SEMAPHORE_H
-    sem_wait(&Future->semaphore);
-    sem_post(&Future->semaphore);
-    Value = Future->value;
-# else
-    pthread_mutex_lock(&Future->mutex);
-    while (!Future->pass) {
-        pthread_cond_wait(&Future->cond, &Future->mutex);
+#if (!defined MR_HIGHLEVEL_CODE) && (defined MR_THREAD_SAFE)
+
+    MR_LOCK(&(Future->lock), ""future.wait"");
+
+    if (Future->signalled) {
+        Value = Future->value;
+        MR_UNLOCK(&(Future->lock), ""future.wait"");
+    } else {
+        /*
+        ** The address of the future can be lost when we resume so save it on
+        ** top of the stack.
+        */
+        MR_incr_sp(1);
+        MR_sv(1) = (MR_Word) Future;
+
+        /*
+        ** Save this context and put it on the list of suspended contexts for
+        ** this future.
+        */
+        MR_save_context(MR_ENGINE(MR_eng_this_context));
+        MR_ENGINE(MR_eng_this_context)->MR_ctxt_resume = &&wait_resume;
+        MR_ENGINE(MR_eng_this_context)->MR_ctxt_next = Future->suspended;
+        Future->suspended = MR_ENGINE(MR_eng_this_context);
+
+        MR_UNLOCK(&(Future->lock), ""future.wait"");
+        MR_runnext();
+
+        assert(0);
+
+    wait_resume:
+
+        /* Restore the address of the future after resuming. */
+        Future = (MR_Future *) MR_sv(1);
+        MR_decr_sp(1);
+
+        assert(Future->signalled == 1);
+        Value = Future->value;
     }
-    Value = Future->value;
-    pthread_mutex_unlock(&Future->mutex);
-# endif
+
+#else
+
+    MR_fatal_error(""internal error: par_builtin.wait"");
+    Value = -1;
+
 #endif
 ").
 
@@ -130,16 +198,32 @@
     signal(Future::in, Value::in),
     [will_not_call_mercury, thread_safe, will_not_modify_trail],
 "
-#ifdef MR_THREAD_SAFE
-# ifdef MR_HAVE_SEMAPHORE_H
+#if (!defined MR_HIGHLEVEL_CODE) && (defined MR_THREAD_SAFE)
+
+    MR_Context *ctxt;
+
+    MR_LOCK(&(Future->lock), ""future.signal"");
+
+    assert(Future->signalled == 0);
+    Future->signalled++;
     Future->value = Value;
-    sem_post(&Future->semaphore);
-# else
-    pthread_mutex_lock(&Future->mutex);
-    Value = Future->value;
-    pthread_cond_broadcast(&Future->cond);
-    pthread_mutex_unlock(&Future->mutex);
-# endif
+
+    /* Schedule all the contexts which are blocking on this future. */
+    ctxt = Future->suspended;
+    while (ctxt != NULL) {
+        MR_schedule(ctxt);
+        ctxt = ctxt->MR_ctxt_next;
+    }
+    Future->suspended = NULL;
+
+    MR_UNLOCK(&(Future->lock), ""future.signal"");
+
+    assert(Future->signalled == 1);
+
+#else
+
+    MR_fatal_error(""internal error: par_builtin.signal"");
+
 #endif
 ").
 
Index: tests/par_conj/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/Mmakefile,v
retrieving revision 1.2
diff -u -r1.2 Mmakefile
--- tests/par_conj/Mmakefile	29 Jun 2006 03:53:34 -0000	1.2
+++ tests/par_conj/Mmakefile	30 Jun 2006 08:41:48 -0000
@@ -47,11 +47,8 @@
 	OBJ_PROGS =
 	PROGS =
 else
-	# Don't run dependent parallel conjunction programs as they can cause
-	# deadlocks if there are not enough threads available.  This will be
-	# fixed with coroutining support.
-	OBJ_PROGS = $(DEP_PAR_CONJ_PROGS)
-	PROGS = $(OBJ_PROGS) $(INDEP_PAR_CONJ_PROGS)
+	OBJ_PROGS =
+	PROGS = $(DEP_PAR_CONJ_PROGS) $(INDEP_PAR_CONJ_PROGS)
 endif
 
 # `mmc --make' doesn't expect subdirectories to appear in targets.
@@ -91,6 +88,16 @@
 
 $(OBJ_PROGS:%=%.runtest): %.runtest: %.$(TARGET_OBJ_EXT) ;
 
+# Exercise multiple Mercury engines in lowlevel grades.
+ENGINES :=
+ifeq "$(filter hl% java% il%,$(GRADE))" ""
+	ENGINES := MERCURY_OPTIONS=-P2
+endif
+
+%.out: %
+	{ [ -f $*.inp ] && cat $*.inp; } | $(ENGINES) ./$< > $@ 2>&1 || \
+		{ grep . $@ /dev/null; exit 1; }
+
 # Run threads_hang with multiple OS threads in lowlevel parallel grades.
 # Repeat the test a few times in increase the chances of getting a deadlock.
 ifeq "$(filter hl% java% il%,$(GRADE))" ""
Index: tests/par_conj/dep_par_1.exp
===================================================================
RCS file: tests/par_conj/dep_par_1.exp
diff -N tests/par_conj/dep_par_1.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_1.exp	28 Jun 2006 05:08:15 -0000
@@ -0,0 +1 @@
+1
Index: tests/par_conj/dep_par_1.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_1.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_1.m
--- tests/par_conj/dep_par_1.m	28 Jun 2006 04:46:21 -0000	1.1
+++ tests/par_conj/dep_par_1.m	30 Jun 2006 08:27:16 -0000
@@ -11,4 +11,5 @@
     & Y = X
     ),
     io.write_int(Y, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
Index: tests/par_conj/dep_par_10.exp
===================================================================
RCS file: tests/par_conj/dep_par_10.exp
diff -N tests/par_conj/dep_par_10.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_10.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+6
Index: tests/par_conj/dep_par_10.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_10.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_10.m
--- tests/par_conj/dep_par_10.m	28 Jun 2006 04:46:21 -0000	1.1
+++ tests/par_conj/dep_par_10.m	30 Jun 2006 08:28:20 -0000
@@ -15,7 +15,8 @@
 	Y = fp(X)
     ),
     io.print(X*Y, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
 
 :- func fp(int) = int.
 
Index: tests/par_conj/dep_par_11.exp
===================================================================
RCS file: tests/par_conj/dep_par_11.exp
diff -N tests/par_conj/dep_par_11.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_11.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+{6, 9, 2}
Index: tests/par_conj/dep_par_11.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_11.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_11.m
--- tests/par_conj/dep_par_11.m	28 Jun 2006 04:46:22 -0000	1.1
+++ tests/par_conj/dep_par_11.m	30 Jun 2006 08:28:24 -0000
@@ -18,4 +18,5 @@
 	U = X + A
     ),
     io.print({X,U,C}, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
Index: tests/par_conj/dep_par_11b.exp
===================================================================
RCS file: tests/par_conj/dep_par_11b.exp
diff -N tests/par_conj/dep_par_11b.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_11b.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+9
Index: tests/par_conj/dep_par_11b.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_11b.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_11b.m
--- tests/par_conj/dep_par_11b.m	28 Jun 2006 04:46:22 -0000	1.1
+++ tests/par_conj/dep_par_11b.m	30 Jun 2006 08:28:35 -0000
@@ -11,7 +11,8 @@
 main(IO0, IO) :-
     p(U),
     io.write_int(U, IO0, IO1),
-    io.nl(IO1, IO).
+    io.nl(IO1, IO2),
+    io.flush_output(IO2, IO).
 
 :- pred p(int::out) is det.
 p(U) :-
Index: tests/par_conj/dep_par_11c.exp
===================================================================
RCS file: tests/par_conj/dep_par_11c.exp
diff -N tests/par_conj/dep_par_11c.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_11c.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+{6, 9, 2}
Index: tests/par_conj/dep_par_11c.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_11c.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_11c.m
--- tests/par_conj/dep_par_11c.m	28 Jun 2006 04:46:22 -0000	1.1
+++ tests/par_conj/dep_par_11c.m	30 Jun 2006 08:28:50 -0000
@@ -11,7 +11,8 @@
 main(IO0, IO) :-
     p(XUC),
     io.print(XUC, IO0, IO1),
-    io.nl(IO1, IO).
+    io.nl(IO1, IO2),
+    io.flush_output(IO2, IO).
 
 :- pred p({int, int, int}::out) is det.
 p({X,U,C}) :-
Index: tests/par_conj/dep_par_12.exp
===================================================================
RCS file: tests/par_conj/dep_par_12.exp
diff -N tests/par_conj/dep_par_12.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_12.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+12
Index: tests/par_conj/dep_par_12.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_12.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_12.m
--- tests/par_conj/dep_par_12.m	28 Jun 2006 04:46:22 -0000	1.1
+++ tests/par_conj/dep_par_12.m	30 Jun 2006 08:28:57 -0000
@@ -27,7 +27,8 @@
     ),
     io.write_int(Y, !IO),
     io.write_int(X, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
 
 :- func f = t.
 :- pragma no_inline(f/0).
Index: tests/par_conj/dep_par_13.exp
===================================================================
RCS file: tests/par_conj/dep_par_13.exp
diff -N tests/par_conj/dep_par_13.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_13.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+[20, 10, 2, 1]
Index: tests/par_conj/dep_par_13.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_13.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_13.m
--- tests/par_conj/dep_par_13.m	28 Jun 2006 04:46:22 -0000	1.1
+++ tests/par_conj/dep_par_13.m	30 Jun 2006 08:29:03 -0000
@@ -25,4 +25,5 @@
 	)
     ),
     io.print(Y, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
Index: tests/par_conj/dep_par_14.exp
===================================================================
RCS file: tests/par_conj/dep_par_14.exp
diff -N tests/par_conj/dep_par_14.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_14.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+1
Index: tests/par_conj/dep_par_14.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_14.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_14.m
--- tests/par_conj/dep_par_14.m	28 Jun 2006 04:46:22 -0000	1.1
+++ tests/par_conj/dep_par_14.m	30 Jun 2006 08:29:10 -0000
@@ -13,7 +13,8 @@
     R = [1, 5, 3, 4, 7, 8, 6, 9, 2, 0],
     p(R, 1, S),
     io.print(S, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
 
 :- pred p(list(int)::in, int::in, int::out) is det.
 
Index: tests/par_conj/dep_par_14b.exp
===================================================================
RCS file: tests/par_conj/dep_par_14b.exp
diff -N tests/par_conj/dep_par_14b.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_14b.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+1
Index: tests/par_conj/dep_par_14b.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_14b.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_14b.m
--- tests/par_conj/dep_par_14b.m	28 Jun 2006 04:46:22 -0000	1.1
+++ tests/par_conj/dep_par_14b.m	30 Jun 2006 08:29:20 -0000
@@ -9,11 +9,12 @@
 :- implementation.
 :- import_module list.
 
-main(!IX) :-
+main(!IO) :-
     R = [1, 5, 3, 4, 7, 8, 6, 9, 2, 0],
     p(R, 1, S),
-    io.print(S, !IX),
-    io.nl(!IX).
+    io.print(S, !IO),
+    io.nl(!IO),
+    io.flush_output(!IO).
 
 :- pred p(list(int)::in, int::in, int::out) is cc_multi.
 
Index: tests/par_conj/dep_par_14c.exp
===================================================================
RCS file: tests/par_conj/dep_par_14c.exp
diff -N tests/par_conj/dep_par_14c.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_14c.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+1
Index: tests/par_conj/dep_par_14c.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_14c.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_14c.m
--- tests/par_conj/dep_par_14c.m	28 Jun 2006 04:46:22 -0000	1.1
+++ tests/par_conj/dep_par_14c.m	30 Jun 2006 08:29:36 -0000
@@ -10,11 +10,12 @@
 :- import_module bool.
 :- import_module list.
 
-main(!IX) :-
+main(!IO) :-
     R = [1, 5, 3, 4, 7, 8, 6, 9, 2, 0],
     p(R, 1, S),
-    io.print(S, !IX),
-    io.nl(!IX).
+    io.print(S, !IO),
+    io.nl(!IO),
+    io.flush_output(!IO).
 
 :- pred p(list(int)::in, int::in, int::out) is cc_multi.
 
Index: tests/par_conj/dep_par_14d.exp
===================================================================
RCS file: tests/par_conj/dep_par_14d.exp
diff -N tests/par_conj/dep_par_14d.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_14d.exp	28 Jun 2006 06:19:00 -0000
@@ -0,0 +1 @@
+1
Index: tests/par_conj/dep_par_14d.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_14d.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_14d.m
--- tests/par_conj/dep_par_14d.m	28 Jun 2006 04:46:22 -0000	1.1
+++ tests/par_conj/dep_par_14d.m	30 Jun 2006 08:29:43 -0000
@@ -15,7 +15,8 @@
     & p(T, A1, S)
     ),
     io.print(S, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
 
 :- pred p(list(int)::in, int::in, int::out) is det.
 
Index: tests/par_conj/dep_par_15.exp
===================================================================
RCS file: tests/par_conj/dep_par_15.exp
diff -N tests/par_conj/dep_par_15.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_15.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+[1, 2, 3, 4, 5, 6, 4, 5, 6, 1, 2, 3]
Index: tests/par_conj/dep_par_16.exp
===================================================================
RCS file: tests/par_conj/dep_par_16.exp
diff -N tests/par_conj/dep_par_16.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_16.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3]
Index: tests/par_conj/dep_par_16.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_16.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_16.m
--- tests/par_conj/dep_par_16.m	28 Jun 2006 04:46:23 -0000	1.1
+++ tests/par_conj/dep_par_16.m	30 Jun 2006 08:29:53 -0000
@@ -15,4 +15,5 @@
     ),
     append(Cs, Ds, Es),
     io.print(Es, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
Index: tests/par_conj/dep_par_17.exp
===================================================================
RCS file: tests/par_conj/dep_par_17.exp
diff -N tests/par_conj/dep_par_17.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_17.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+3
Index: tests/par_conj/dep_par_17.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_17.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_17.m
--- tests/par_conj/dep_par_17.m	28 Jun 2006 04:46:23 -0000	1.1
+++ tests/par_conj/dep_par_17.m	30 Jun 2006 08:30:02 -0000
@@ -11,7 +11,8 @@
 main(!IO) :-
     p(t1, X),
     io.write_int(X, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
 
 :- type t ---> t1 ; t2.
 
Index: tests/par_conj/dep_par_18.exp
===================================================================
RCS file: tests/par_conj/dep_par_18.exp
diff -N tests/par_conj/dep_par_18.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_18.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+[0, 1, 2, 3, 4, 5]
Index: tests/par_conj/dep_par_18.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_18.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_18.m
--- tests/par_conj/dep_par_18.m	28 Jun 2006 04:46:23 -0000	1.1
+++ tests/par_conj/dep_par_18.m	30 Jun 2006 08:30:10 -0000
@@ -11,7 +11,8 @@
 main(!IO) :-
     integers(0, 5, R),
     io.print(R, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
 
 :- pred integers(int::in, int::in, list(int)::out) is det.
 
Index: tests/par_conj/dep_par_19.exp
===================================================================
RCS file: tests/par_conj/dep_par_19.exp
diff -N tests/par_conj/dep_par_19.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_19.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+12
Index: tests/par_conj/dep_par_2.exp
===================================================================
RCS file: tests/par_conj/dep_par_2.exp
diff -N tests/par_conj/dep_par_2.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_2.exp	28 Jun 2006 05:08:46 -0000
@@ -0,0 +1 @@
+3
Index: tests/par_conj/dep_par_2.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_2.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_2.m
--- tests/par_conj/dep_par_2.m	28 Jun 2006 04:46:23 -0000	1.1
+++ tests/par_conj/dep_par_2.m	30 Jun 2006 08:21:26 -0000
@@ -15,7 +15,8 @@
 	p(X, Y)
     ),
     io.write_int(Y, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
 
 :- pred p(int::in, int::out) is det.
 p(X, X+1).
Index: tests/par_conj/dep_par_20.exp
===================================================================
RCS file: tests/par_conj/dep_par_20.exp
diff -N tests/par_conj/dep_par_20.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_20.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+t
Index: tests/par_conj/dep_par_20.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_20.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_20.m
--- tests/par_conj/dep_par_20.m	28 Jun 2006 04:46:23 -0000	1.1
+++ tests/par_conj/dep_par_20.m	30 Jun 2006 08:30:18 -0000
@@ -19,7 +19,8 @@
     & q(X, Y)
     ),
     io.print(Y, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
 
 :- pred q(t::in, t::out) is det.
 :- pragma no_inline(q/2).
Index: tests/par_conj/dep_par_21.exp
===================================================================
RCS file: tests/par_conj/dep_par_21.exp
diff -N tests/par_conj/dep_par_21.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_21.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+[1, 2, 4, 5]
Index: tests/par_conj/dep_par_21.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_21.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_21.m
--- tests/par_conj/dep_par_21.m	28 Jun 2006 04:46:23 -0000	1.1
+++ tests/par_conj/dep_par_21.m	30 Jun 2006 08:30:23 -0000
@@ -17,7 +17,8 @@
 main(!IO) :-
     remove(3, 1..5, Res),
     io.print(Res, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
 
 :- pred remove(int::in, list(int)::in, list(int)::out) is det.
 
Index: tests/par_conj/dep_par_22.exp
===================================================================
RCS file: tests/par_conj/dep_par_22.exp
diff -N tests/par_conj/dep_par_22.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_22.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+up
Index: tests/par_conj/dep_par_22.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_22.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_22.m
--- tests/par_conj/dep_par_22.m	28 Jun 2006 04:46:23 -0000	1.1
+++ tests/par_conj/dep_par_22.m	30 Jun 2006 08:30:27 -0000
@@ -19,7 +19,8 @@
 main(!IO) :-
     p(up, X),
     io.print(X, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
 
 :- type t
     --->    up
Index: tests/par_conj/dep_par_23.exp
===================================================================
RCS file: tests/par_conj/dep_par_23.exp
diff -N tests/par_conj/dep_par_23.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_23.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+[3, 4, 5]
Index: tests/par_conj/dep_par_23.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_23.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_23.m
--- tests/par_conj/dep_par_23.m	28 Jun 2006 04:46:23 -0000	1.1
+++ tests/par_conj/dep_par_23.m	30 Jun 2006 08:30:31 -0000
@@ -13,4 +13,5 @@
     L0 = [1, 2, 3],
     L = list.map((func(X) = Y :- Z=X+1 & Y=Z+1), L0),
     io.print(L, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
Index: tests/par_conj/dep_par_3.exp
===================================================================
RCS file: tests/par_conj/dep_par_3.exp
diff -N tests/par_conj/dep_par_3.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_3.exp	28 Jun 2006 05:08:50 -0000
@@ -0,0 +1 @@
+2
Index: tests/par_conj/dep_par_3.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_3.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_3.m
--- tests/par_conj/dep_par_3.m	28 Jun 2006 04:46:23 -0000	1.1
+++ tests/par_conj/dep_par_3.m	30 Jun 2006 08:27:24 -0000
@@ -15,7 +15,8 @@
 	Y = f(X)
     ),
     io.write_int(X*Y, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
 
 :- func f(int) = int.
 :- pragma no_inline(f/1).
Index: tests/par_conj/dep_par_3b.exp
===================================================================
RCS file: tests/par_conj/dep_par_3b.exp
diff -N tests/par_conj/dep_par_3b.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_3b.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+2
Index: tests/par_conj/dep_par_3b.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_3b.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_3b.m
--- tests/par_conj/dep_par_3b.m	28 Jun 2006 04:46:24 -0000	1.1
+++ tests/par_conj/dep_par_3b.m	30 Jun 2006 08:30:37 -0000
@@ -15,7 +15,8 @@
 	Y = (if f(X) then 2 else 0)
     ),
     io.write_int(Y, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
 
 :- pred f(int::in) is semidet.
 :- pragma no_inline(f/1).
Index: tests/par_conj/dep_par_3c.exp
===================================================================
RCS file: tests/par_conj/dep_par_3c.exp
diff -N tests/par_conj/dep_par_3c.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_3c.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+3
Index: tests/par_conj/dep_par_3c.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_3c.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_3c.m
--- tests/par_conj/dep_par_3c.m	28 Jun 2006 04:46:24 -0000	1.1
+++ tests/par_conj/dep_par_3c.m	30 Jun 2006 08:30:40 -0000
@@ -15,7 +15,8 @@
 	Y = (if f(X) then 2 else 0)
     ),
     io.write_int(X+Y, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
 
 :- pred f(int::in) is semidet.
 :- pragma no_inline(f/1).
Index: tests/par_conj/dep_par_4.exp
===================================================================
RCS file: tests/par_conj/dep_par_4.exp
diff -N tests/par_conj/dep_par_4.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_4.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+3
Index: tests/par_conj/dep_par_4.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_4.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_4.m
--- tests/par_conj/dep_par_4.m	28 Jun 2006 04:46:24 -0000	1.1
+++ tests/par_conj/dep_par_4.m	30 Jun 2006 08:27:29 -0000
@@ -16,7 +16,8 @@
 	Y = f(X)
     ),
     io.print(Y, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
 
 :- func f(int) = int.
 f(X) = X+1.
Index: tests/par_conj/dep_par_5.exp
===================================================================
RCS file: tests/par_conj/dep_par_5.exp
diff -N tests/par_conj/dep_par_5.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_5.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+1
Index: tests/par_conj/dep_par_5.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_5.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_5.m
--- tests/par_conj/dep_par_5.m	28 Jun 2006 04:46:24 -0000	1.1
+++ tests/par_conj/dep_par_5.m	30 Jun 2006 08:27:33 -0000
@@ -14,4 +14,5 @@
     &
 	io.write_int(U, !IO)
     ),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
Index: tests/par_conj/dep_par_5b.exp
===================================================================
RCS file: tests/par_conj/dep_par_5b.exp
diff -N tests/par_conj/dep_par_5b.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_5b.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+12
Index: tests/par_conj/dep_par_5b.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_5b.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_5b.m
--- tests/par_conj/dep_par_5b.m	28 Jun 2006 04:46:24 -0000	1.1
+++ tests/par_conj/dep_par_5b.m	30 Jun 2006 08:30:49 -0000
@@ -14,4 +14,5 @@
     &
 	io.write_int(2, !IO)
     ),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
Index: tests/par_conj/dep_par_5c.exp
===================================================================
RCS file: tests/par_conj/dep_par_5c.exp
diff -N tests/par_conj/dep_par_5c.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_5c.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+1
Index: tests/par_conj/dep_par_5c.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_5c.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_5c.m
--- tests/par_conj/dep_par_5c.m	28 Jun 2006 04:46:24 -0000	1.1
+++ tests/par_conj/dep_par_5c.m	30 Jun 2006 08:31:09 -0000
@@ -11,7 +11,8 @@
 main(IO0, IO) :-
     (
 	io.write_int(1, IO0, IO1),
-	io.nl(IO1, IO)
+	io.nl(IO1, IO2)
     &
 	true
-    ).
+    ),
+    io.flush_output(IO2, IO).
Index: tests/par_conj/dep_par_5d.exp
===================================================================
RCS file: tests/par_conj/dep_par_5d.exp
diff -N tests/par_conj/dep_par_5d.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_5d.exp	28 Jun 2006 06:15:52 -0000
@@ -0,0 +1 @@
+12
Index: tests/par_conj/dep_par_5d.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_5d.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_5d.m
--- tests/par_conj/dep_par_5d.m	28 Jun 2006 04:46:24 -0000	1.1
+++ tests/par_conj/dep_par_5d.m	30 Jun 2006 08:31:30 -0000
@@ -11,7 +11,8 @@
 main(IO0, IO) :-
     (
 	io.write_int(1, IO0, IO1)
-    ,
+    &
 	io.write_int(2, IO1, IO2),
-	io.nl(IO2, IO)
+	io.nl(IO2, IO3),
+	io.flush_output(IO3, IO)
     ).
Index: tests/par_conj/dep_par_6.exp
===================================================================
RCS file: tests/par_conj/dep_par_6.exp
diff -N tests/par_conj/dep_par_6.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_6.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+1
Index: tests/par_conj/dep_par_6.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_6.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_6.m
--- tests/par_conj/dep_par_6.m	28 Jun 2006 04:46:24 -0000	1.1
+++ tests/par_conj/dep_par_6.m	30 Jun 2006 08:27:37 -0000
@@ -16,4 +16,5 @@
 	Y = X
     ),
     io.print(Y, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
Index: tests/par_conj/dep_par_7.exp
===================================================================
RCS file: tests/par_conj/dep_par_7.exp
diff -N tests/par_conj/dep_par_7.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_7.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+1
Index: tests/par_conj/dep_par_7.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_7.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_7.m
--- tests/par_conj/dep_par_7.m	28 Jun 2006 04:46:24 -0000	1.1
+++ tests/par_conj/dep_par_7.m	30 Jun 2006 08:45:04 -0000
@@ -16,4 +16,5 @@
 	Y = 2
     ),
     io.write_int(Y, IO0, IO1),
-    io.nl(IO1, IO).
+    io.nl(IO1, IO2),
+    io.flush_output(IO2, IO).
Index: tests/par_conj/dep_par_8.exp
===================================================================
RCS file: tests/par_conj/dep_par_8.exp
diff -N tests/par_conj/dep_par_8.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_8.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+1
Index: tests/par_conj/dep_par_8.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_8.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_8.m
--- tests/par_conj/dep_par_8.m	28 Jun 2006 04:46:25 -0000	1.1
+++ tests/par_conj/dep_par_8.m	30 Jun 2006 08:45:24 -0000
@@ -18,4 +18,5 @@
 	Y = X
     ),
     io.write_int(Y, IO0, IO1),
-    io.nl(IO1, IO).
+    io.nl(IO1, IO2),
+    io.flush_output(IO2, IO).
Index: tests/par_conj/dep_par_9.exp
===================================================================
RCS file: tests/par_conj/dep_par_9.exp
diff -N tests/par_conj/dep_par_9.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_9.exp	28 Jun 2006 05:09:15 -0000
@@ -0,0 +1 @@
+6
Index: tests/par_conj/dep_par_9.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/dep_par_9.m,v
retrieving revision 1.1
diff -u -r1.1 dep_par_9.m
--- tests/par_conj/dep_par_9.m	28 Jun 2006 04:46:25 -0000	1.1
+++ tests/par_conj/dep_par_9.m	30 Jun 2006 08:31:44 -0000
@@ -16,7 +16,8 @@
 	Y = HO(X)
     ),
     io.print(X*Y, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
 
 :- func get_ho = (func(int) = int).
 :- pragma no_inline(get_ho/0).
Index: tests/par_conj/indep_par_append.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/indep_par_append.m,v
retrieving revision 1.1
diff -u -r1.1 indep_par_append.m
--- tests/par_conj/indep_par_append.m	28 Jun 2006 04:46:25 -0000	1.1
+++ tests/par_conj/indep_par_append.m	30 Jun 2006 08:31:48 -0000
@@ -15,4 +15,5 @@
     ),
     append(Cs, Ds, Es),
     io.print(Es, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
Index: tests/par_conj/indep_par_nested.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/indep_par_nested.m,v
retrieving revision 1.1
diff -u -r1.1 indep_par_nested.m
--- tests/par_conj/indep_par_nested.m	28 Jun 2006 04:46:25 -0000	1.1
+++ tests/par_conj/indep_par_nested.m	30 Jun 2006 08:31:51 -0000
@@ -36,4 +36,5 @@
         )
     ),
     io.print({A,B,C,D,E,F,G,H,I,J,K,L}, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
Index: tests/par_conj/threads_hang.m
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/threads_hang.m,v
retrieving revision 1.1
diff -u -r1.1 threads_hang.m
--- tests/par_conj/threads_hang.m	29 Jun 2006 03:53:35 -0000	1.1
+++ tests/par_conj/threads_hang.m	30 Jun 2006 08:31:57 -0000
@@ -13,7 +13,8 @@
 main(!IO) :-
     fib(11, F),
     io.write_int(F, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    io.flush_output(!IO).
 
 :- pred fib(int::in, int::out) is det.
 
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list