[m-rev.] for review: fix handling of contexts in engines

Zoltan Somogyi zs at csse.unimelb.edu.au
Fri Apr 13 20:54:34 AEST 2007


For review by Peter Wang.

Zoltan.

Fix some software rot that prevented I/O operations from working in mmos
grades. The problem was the change to the I/O module to make it use thread
local storage via a new field of the MR_Context structure which was accessed
via the MR_eng_this_context field of the engine, instead of via the
MR_eng_context field. The new field was not set by the code for initializing
the contexts used by own stack minimal model tabling.

runtime/mercury_context.h:
runtime/mercury_engine.h:
	Add significant new documentation about how fields of the MR_Context
	structure are accessed, both because the documentation is useful and to
	make similar mistakes less likely in future.

	Add a macro for use by own stack minimal model tabling.

runtime/mercury_thread.c:
	Add a comment about a link to mercury_engine.h.

runtime/mercury_thread.h:
	Convert to four-space indentation, and fix some formatting.

runtime/mercury_mm_own_stacks.c:
	Add code for filling in the missing fields of newly created contexts.

runtime/mercury_wrapper.c:
	In own stack minimal model grades, set up the main context properly.
	The previous code was based on a flawed understanding of the
	relationalship between MR_eng_context and MR_eng_this_context.

tests/debugger/mmos_print.{m,inp,exp}:
	Add a new test case (which we don't yet pass due to a problem with
	formatting of mdb output) to test the fix. The old versions of the
	compiler don't pass this test case, because the "p *" commands of the
	debugger invoke I/O code in the Mercury standard library, which fails
	with a segfault due to the thread local fields of generators' contexts
	being unitialized.

	Note that the .inp aborts execution, because without the abort the
	execution would go into an infinite loop since mmos grades don't yet
	have code for detecting completion.

tests/debugger/Mmakefile:
	Enable the new test case in mmos grades.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/stream/tests
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/mercury_context.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_context.h,v
retrieving revision 1.40
diff -u -b -r1.40 mercury_context.h
--- runtime/mercury_context.h	3 Mar 2007 03:43:34 -0000	1.40
+++ runtime/mercury_context.h	13 Apr 2007 08:18:56 -0000
@@ -66,10 +66,32 @@
 #endif
 
 /*
-** MR_Context structures have the following fields:
+** Each engine has one MR_Context structure loaded into it (in the engine field
+** named MR_eng_context) from a context which is pointed to by the engine's
+** MR_eng_this_context field. Fields which can be expected to be accessed at
+** least several times between context switches are accessed via MR_eng_context
+** while the rest are accessed via MR_eng_this_context (which requires
+** following an extra pointer). Note that some fields are further cached
+** in abstract machine registers, and some in fact are only ever accessed
+** via these abstract machine registers. The saved copies of some these
+** abstract machine registers are kept not in the named fields below, but in
+** the engine's fake reg array.
+**
+** All fields accessed via MR_eng_context and via abstract machine registers
+** should be mentioned in the MR_save_context and MR_load_context macros.
+** All fields accessed via MR_eng_this_context should be mentioned in the
+** MR_copy_eng_this_context_fields macro. All fields accessed via direct
+** specification of the context need explicit code to set them in all places
+** where we create new contexts: in the mercury_thread module for parallelism,
+** and in the mercury_mm_own_stacks module for minimal model tabling.
+**
+** The context structure has the following fields. The documentation of each
+** field says how it is accessed, but please take this info with a pinch of
+** salt; I (zs) don't guarantee its accuracy.
 **
 ** id               A string to identify the context for humans who want to
 **                  debug the handling of contexts.
+**                  (Not accessed.)
 **
 ** size             Whether this context has regular-sized stacks or smaller
 **                  stacks. Some parallel programs can allocate many contexts
@@ -77,6 +99,7 @@
 **                  large stacks. We allocate contexts with "smaller" stacks
 **                  for parallel computations (although whether they are
 **                  actually smaller is up to the user).
+**                  (Accessed only when directly specifying the context.)
 **
 ** next             If this context is in the free-list `next' will point to
 **                  the next free context. If this context is suspended waiting
@@ -84,9 +107,11 @@
 **                  next waiting context. If this context is runnable but not
 **                  currently running then `next' points to the next runnable
 **                  context in the runqueue.
+**                  (Accessed only when directly specifying the context.)
 **
 ** resume           A pointer to the code at which execution should resume
 **                  when this context is next scheduled.
+**                  (Accessed via MR_eng_this_context.)
 **
 ** resume_owner_thread
 ** resume_c_depth
@@ -96,6 +121,7 @@
 **                  executed by any engine. Otherwise the resume_owner_thread
 **                  and resume_c_depth must match the engine's owner_thread
 **                  and c_depth. See the comments in mercury_engine.h.
+**                  (Both accessed only when directly specifying the context.)
 **
 ** saved_owners
 **                  A stack used to record the Mercury engines on which this
@@ -103,45 +129,65 @@
 **                  Mercury. We must execute this context in the correct
 **                  engine when returning to those C calls.  See the comments
 **                  in mercury_engine.h.
+**                  (Accessed via MR_eng_this_context.)
 **
 ** succip           The succip for this context.
+**                  (Accessed via abstract machine register.)
 **
 ** detstack_zone    The current detstack zone for this context.
 ** prev_detstack_zones
 **                  A list of any previous detstack zones for this context.
+**                  (Both accessed via MR_eng_context.)
 ** sp               The saved sp for this context.
+**                  (Accessed via abstract machine register.)
 **
 ** nondetstack_zone The current nondetstack zone for this context.
 ** prev_nondetstack_zones
 **                  A list of any previous nondetstack zones for this context.
+**                  (Both accessed via MR_eng_context.)
 ** curfr            The saved curfr for this context.
 ** maxfr            The saved maxfr for this context.
+**                  (Both accessed via abstract machine register.)
 **
 ** genstack_zone    The generator stack zone for this context.
+**                  (Accessed via MR_eng_context.)
 ** gen_next         The saved gen_next for this context.
+**                  (Accessed via abstract machine register.)
 **
 ** cutstack_zone    The cut stack zone for this context.
+**                  (Accessed via MR_eng_context.)
 ** cut_next         The saved cut_next for this context.
+**                  (Accessed via abstract machine register.)
 **
 ** pnegstack_zone   The possibly_negated_context stack zone for this context.
+**                  (Accessed via MR_eng_context.)
 ** pneg_next        The saved pneg_next for this context.
+**                  (Accessed via abstract machine register.)
 **
 ** parent_sp        The saved parent_sp for this context.
+**                  (Accessed via abstract machine register.)
+**
 ** spark_stack      The sparks generated by this context, in a stack.
+**                  (Accessed usually by explicitly specifying the context,
+**                  but also via MR_eng_this_context.)
 **
 ** trail_zone       The trail zone for this context.
 ** trail_ptr        The saved MR_trail_ptr for this context.
 ** ticket_counter   The saved MR_ticket_counter for this context.
 ** ticket_highwater The saved MR_ticket_high_water for this context.
+**                  (All accessed via abstract machine register.)
 **
 ** hp               The saved hp for this context.
+**                  (Accessed via abstract machine register.)
 **
 ** min_hp_rec       This pointer marks the minimum value of MR_hp to which
 **                  we can truncate the heap on backtracking. See comments
 **                  before the macro MR_set_min_heap_reclamation_point below.
+**                  (Accessed via abstract machine register.)
 **
 ** thread_local_mutables
 **                  The array of thread-local mutable values for this context.
+**                  (Accessed via MR_eng_this_context.)
 */
 
 typedef struct MR_Context_Struct        MR_Context;
@@ -647,6 +693,16 @@
         MR_save_hp_in_context(save_context_c);                                \
     } while (0)
 
+#define MR_copy_eng_this_context_fields(to_cptr, from_cptr)                   \
+    do {                                                                      \
+        to_cptr->MR_ctxt_resume = from_cptr->MR_ctxt_resume;                  \
+        to_cptr->MR_ctxt_thread_local_mutables =                              \
+            from_cptr->MR_ctxt_thread_local_mutables;                         \
+        /* it wouldn't be appropriate to copy the spark_stack field */        \
+        /* it wouldn't be appropriate to copy the saved_owners field */       \
+    } while (0)
+
+
 /*
 ** If you change MR_Sync_Term_Struct you need to update configure.in.
 */
Index: runtime/mercury_engine.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_engine.h,v
retrieving revision 1.46
diff -u -b -r1.46 mercury_engine.h
--- runtime/mercury_engine.h	3 Mar 2007 03:43:35 -0000	1.46
+++ runtime/mercury_engine.h	13 Apr 2007 02:49:37 -0000
@@ -275,19 +275,31 @@
 **
 ** global_hp    The global heap pointer for this engine.
 **
-** this_context Points to the context currently executing on this engine.
-**
-** context      This field stores all the context information for the context
+** this_context Points to the "backing store" for the context currently
+**              executing on this engine.
+** context      Stores all the context information for the context currently
 **              executing in this engine.
 **
-**              MR_init_engine, invoked by mercury_runtime_init in
-**              mercury_wrapper.c through MR_init_thread and MR_create_engine,
-**              sets up the initial context for the engine, and puts the
-**              pointer to it in the this_context field. Later,
-**              mercury_runtime_init invokes MR_save_context to copy the info
-**              from there into the context field. Beyond this, the
-**              relationship between the this_context and context fields
-**              is not well documented XXX.
+**              Conceptually, we could access all information relating to the
+**              current context via the MR_eng_this_context field. However,
+**              that would require an extra indirection on most accesses,
+**              including all accesses to the stack, abstract machine registers
+**              etc. That would be too high a cost. We therefore bodily include
+**              a context into the engine (in the MR_eng_context) field, and
+**              load most of the things pointed to by the MR_eng_this_context
+**              field into MR_eng_context. "Most", not "all", because some
+**              fields are so rarely accessed that we don't expect the extra
+**              cost of context switching to be compensated for by reduced
+**              access costs between context switches. These fields are
+**              therefore accessed directly via MR_eng_this_context. The big
+**              comment in mercury_context.h documents, for each field of the
+**              context structure, whether it is accessed by MR_eng_context or
+**              via MR_eng_this_context.
+**
+**              MR_init_thread, invoked by mercury_runtime_init in
+**              mercury_wrapper.c, creates the initial MR_eng_this_context
+**              for the engine, and then invokes MR_load_context to copy the
+**              info from there into the MR_eng_context field.
 **
 ** main_context The context of the main computation. The owner_generator field
 **              of this context must be NULL.
Index: runtime/mercury_mm_own_stacks.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_mm_own_stacks.c,v
retrieving revision 1.10
diff -u -b -r1.10 mercury_mm_own_stacks.c
--- runtime/mercury_mm_own_stacks.c	18 Feb 2007 08:01:56 -0000	1.10
+++ runtime/mercury_mm_own_stacks.c	13 Apr 2007 08:18:55 -0000
@@ -556,6 +556,14 @@
         MR_next_gen_context++;
         ctxt = MR_create_context(strdup(buf), MR_CONTEXT_SIZE_SMALL,
             generator);
+        MR_copy_eng_this_context_fields(ctxt, MR_ENGINE(MR_eng_this_context));
+        ctxt->MR_ctxt_next = NULL;
+#ifdef  MR_THREAD_SAFE
+        ctxt->MR_ctxt_resume_owner_thread = NULL;
+        ctxt->MR_ctxt_resume_c_depth = 0;
+        ctxt->MR_ctxt_saved_owners = NULL;
+#endif
+        ctxt->MR_ctxt_spark_stack = NULL;
     }
 
     ctxt->MR_ctxt_owner_generator = generator;
Index: runtime/mercury_thread.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_thread.c,v
retrieving revision 1.31
diff -u -b -r1.31 mercury_thread.c
--- runtime/mercury_thread.c	3 Mar 2007 03:43:35 -0000	1.31
+++ runtime/mercury_thread.c	13 Apr 2007 02:49:39 -0000
@@ -131,6 +131,11 @@
             return MR_FALSE;
 
         case MR_use_now :
+            /*
+            ** The following is documented in mercury_engine.h, so any
+            ** changes here may need changes there as well.
+            */
+
             if (MR_ENGINE(MR_eng_this_context) == NULL) {
                 MR_ENGINE(MR_eng_this_context) =
                     MR_create_context("init_thread",
@@ -148,6 +153,7 @@
 /* 
 ** Release resources associated with this thread.
 */
+
 void
 MR_finalize_thread_engine(void)
 {
Index: runtime/mercury_thread.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_thread.h,v
retrieving revision 1.21
diff -u -b -r1.21 mercury_thread.h
--- runtime/mercury_thread.h	1 Feb 2007 08:08:00 -0000	1.21
+++ runtime/mercury_thread.h	13 Apr 2007 08:09:56 -0000
@@ -1,4 +1,7 @@
 /*
+** vim: ts=4 sw=4 expandtab
+*/
+/*
 ** Copyright (C) 1997-1998, 2000, 2003, 2005-2007 The University of Melbourne.
 ** This file may only be copied under the terms of the GNU Library General
 ** Public License - see the file COPYING.LIB in the Mercury distribution.
@@ -244,7 +247,9 @@
     (MR_ENGINE(MR_eng_this_context)->MR_ctxt_thread_local_mutables)
 
 #define MR_SET_THREAD_LOCAL_MUTABLES(tlm)                                \
-    (MR_THREAD_LOCAL_MUTABLES = tlm)
+    do {                                                                \
+        MR_THREAD_LOCAL_MUTABLES = (tlm);                               \
+    } while (0)
 
 #define MR_get_thread_local_mutable(type, var, mut_index)                \
     do {                                                                 \
@@ -252,7 +257,7 @@
                                                                          \
         tlm = MR_THREAD_LOCAL_MUTABLES;                                  \
         MR_LOCK(&tlm->MR_tlm_lock, "MR_get_thread_local_mutable");       \
-        var = *((type *) &tlm->MR_tlm_values[mut_index]);                \
+        var = * ((type *) &tlm->MR_tlm_values[(mut_index)]);            \
         MR_UNLOCK(&tlm->MR_tlm_lock, "MR_get_thread_local_mutable");     \
     } while (0)
 
@@ -262,7 +267,7 @@
                                                                          \
         tlm = MR_THREAD_LOCAL_MUTABLES;                                  \
         MR_LOCK(&tlm->MR_tlm_lock, "MR_set_thread_local_mutable");       \
-        *((type *) &tlm->MR_tlm_values[mut_index]) = var;                \
+        * ((type *) &tlm->MR_tlm_values[(mut_index)]) = (var);          \
         MR_UNLOCK(&tlm->MR_tlm_lock, "MR_set_thread_local_mutable");     \
     } while (0)
 
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.180
diff -u -b -r1.180 mercury_wrapper.c
--- runtime/mercury_wrapper.c	13 Feb 2007 06:30:13 -0000	1.180
+++ runtime/mercury_wrapper.c	13 Apr 2007 02:54:28 -0000
@@ -595,10 +595,12 @@
   #ifdef MR_THREAD_SAFE
     {
         int i;
+
         MR_exit_now = MR_FALSE;
         for (i = 1 ; i < MR_num_threads ; i++) {
             MR_create_thread(NULL);
         }
+
         while (MR_num_idle_engines < MR_num_threads-1) {
             /* busy wait until the worker threads are ready */
         }
@@ -676,9 +678,7 @@
 #endif
 
 #ifdef  MR_USE_MINIMAL_MODEL_OWN_STACKS
-    MR_ENGINE(MR_eng_main_context) = MR_NEW(MR_Context);
-    MR_save_context(MR_ENGINE(MR_eng_main_context));
-    MR_ENGINE(MR_eng_this_context) = MR_ENGINE(MR_eng_main_context);
+    MR_ENGINE(MR_eng_main_context) = MR_ENGINE(MR_eng_this_context);
 #endif
 
     /*
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
Index: tests/debugger/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/Mmakefile,v
retrieving revision 1.130
diff -u -b -r1.130 Mmakefile
--- tests/debugger/Mmakefile	23 Feb 2007 06:35:55 -0000	1.130
+++ tests/debugger/Mmakefile	13 Apr 2007 08:20:51 -0000
@@ -160,10 +160,17 @@
     endif
 endif
 
+# The mmos_print test is meant to be used in mmos grades only.
+ifneq "$(findstring mmos,$(GRADE))" ""
+    MMOS_PROGS = mmos_print
+else 
+    MMOS_PROGS =
+endif
+
 ALL_RETRY_PROGS = $(RETRY_PROGS) $(INTERACTIVE_PROGS)
 ALL_NONRETRY_PROGS = $(NONRETRY_PROGS) $(SENSITIVE_PROGS) \
 			$(SHALLOW_PROGS) $(DEBUG_GRADE_PROGS) $(ENUM_PROGS) \
-			$(TERM_SIZE_PROGS)
+			$(TERM_SIZE_PROGS) $(MMOS_PROGS)
 
 # Debugging doesn't yet don't work in MLDS grades (hl*, il*, and java),
 # and the retry command doesn't and will not work in deep profiling
@@ -432,6 +439,10 @@
 	$(MDB) ./no_inline_builtins < no_inline_builtins.inp \
 		> no_inline_builtins.out 2>&1
 
+mmos_print.out: mmos_print mmos_print.inp
+	$(MDB) ./mmos_print < mmos_print.inp \
+		> mmos_print.out 2>&1
+
 # We need to pipe the output through sed to avoid hard-coding dependencies on
 # particular line numbers in the standard library source code.
 output_term_dep.out: output_term_dep output_term_dep.inp
Index: tests/debugger/mmos_print.exp
===================================================================
RCS file: tests/debugger/mmos_print.exp
diff -N tests/debugger/mmos_print.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/mmos_print.exp	13 Apr 2007 08:23:38 -0000
@@ -0,0 +1,23 @@
+       1:      1  1 CALL pred mmos_print.main/2-0 (det) mmos_print.m:13
+mdb> echo on
+Command echo enabled.
+mdb> register --quiet
+mdb> print *
+mdb: there are no live variables.
+mdb> step
+       2:      2  2 CALL pred mmos_print.tc/2-0 (nondet) mmos_print.m:21
+mdb> print *
+       A (arg 1)              	1
+mdb> step
+tc(1)        1:      1  1 CALL pred mmos_print.GeneratorFor_tc/1-0 (nondet) mmos_print.m:21
+mdb> print *
+mdb: there are no live variables.
+mdb> step
+tc(1)        2:      2  2 CALL pred mmos_print.edge/2-0 (nondet) mmos_print.m:31 (mmos_print.m:22)
+mdb> print *
+       HeadVar__1             	1
+mdb> step
+tc(1)        3:      2  2 SWTC pred mmos_print.edge/2-0 (nondet) s1-na; mmos_print.m:31
+mdb> print *
+       HeadVar__1             	1
+mdb> quit -y
Index: tests/debugger/mmos_print.inp
===================================================================
RCS file: tests/debugger/mmos_print.inp
diff -N tests/debugger/mmos_print.inp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/mmos_print.inp	13 Apr 2007 08:21:18 -0000
@@ -0,0 +1,12 @@
+echo on
+register --quiet
+print *
+step
+print *
+step
+print *
+step
+print *
+step
+print *
+quit -y
Index: tests/debugger/mmos_print.m
===================================================================
RCS file: tests/debugger/mmos_print.m
diff -N tests/debugger/mmos_print.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/mmos_print.m	13 Apr 2007 05:11:21 -0000
@@ -0,0 +1,34 @@
+:- module mmos_print.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module solutions, list.
+
+main(!IO) :-
+	solutions(tc(1), Solns),
+	io.write(Solns, !IO),
+	io.nl(!IO).
+
+:- pred tc(int::in, int::out) is nondet.
+:- pragma minimal_model(tc/2).
+
+tc(A, B) :-
+	edge(A, C),
+	(
+		B = C
+	;
+		tc(C, B)
+	).
+
+:- pred edge(int::in, int::out) is nondet.
+
+edge(1, 2).
+edge(1, 3).
+edge(2, 1).
+edge(3, 4).
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
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