[m-rev.] for review: trail resets

Julien Fischer juliensf at csse.unimelb.edu.au
Wed Jun 11 19:20:35 AEST 2008


This is still pending further testing and bootchecking in various
trailing grades.  I won't update the reference manual just yet as this
is still fairly experimental.

Estimated hours taken: 3
Branches: main

Provide a mechanism for resetting the trail.  This allows the reuse of
memory that is occupied by any entries on the trail.  This can only be done
safely after it is certain that any calls that added the trail entries
cannot be backtracked over.  For some programs doing this can prevent trail
exhaustation.

This diff does not provide a way of doing this at the Mercury level, nor
can the compiler currently automatically add calls to reclaim memory used
by trail.  Both these things are future work.

XXX the interaction between this and the debugger is a bit unclear since
trailing and debugging don't currently work together properly.

runtime/mercury_trail.h:
runtime/mercury_trail.c:
 	Add a new function MR_reset_trail().  When called this
 	function walks back along the trail calling function trail entries
 	with the MR_gc untrail reason.  It then zeros out the trail zone
 	and resets the ticket counter and ticket high water mark to their
 	initial values.

 	Define two macros, MR_TRAIL_ZONE and MR_TRAIL_BASE that expand
 	to the addresses of the trail zone and the base of the trail
 	respectively in a grade independent manner.

 	Redefine MR_num_trail_entries() using the MR_TRAIL_BASE macro.

 	Document that MR_gc is now used for this.

 	Fix a typo.

tests/trailing/Mmakefile:
tests/trailing/test_trail_reset.m:
tests/trailing/test_trail_reset.exp:
 	A test of the trail reset functionality.

Julien.

Index: runtime/mercury_trail.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_trail.c,v
retrieving revision 1.15
diff -u -r1.15 mercury_trail.c
--- runtime/mercury_trail.c	10 Jun 2008 04:05:00 -0000	1.15
+++ runtime/mercury_trail.c	11 Jun 2008 08:33:39 -0000
@@ -22,6 +22,28 @@

  #ifdef MR_USE_TRAIL

+/*
+** The following macros are used to access (parts of) the trail zone in a
+** grade independent manner.
+** 
+** MR_TRAIL_ZONE expands to the address of the trail zone for the current
+** thread.
+**
+** MR_TRAIL_BASE expands to the address of the base of the trail for the
+** current thread, i.e. the initial value to which MR_trail_ptr_var is set.
+**
+*/
+#if defined(MR_THREAD_SAFE)
+
+    #define MR_TRAIL_ZONE (MR_CONTEXT(MR_ctx_trail_zone))
+
+    #define MR_TRAIL_BASE \
+        ((MR_TrailEntry *) (MR_CONTEXT(MR_ctx_trail_zone)->MR_zone_min));
+#else
+    #define MR_TRAIL_ZONE   MR_trail_zone
+    #define MR_TRAIL_BASE   ((MR_TrailEntry *) (MR_trail_zone->MR_zone_min))
+#endif
+
  #if !defined(MR_THREAD_SAFE)
  MR_MemoryZone   *MR_trail_zone;
  MR_TrailEntry   *MR_trail_ptr_var;
@@ -81,18 +103,39 @@
      }
  }

+/*---------------------------------------------------------------------------*/
+

  MR_Unsigned
  MR_num_trail_entries(void)
  {
-#if defined(MR_THREAD_SAFE)
-    return MR_trail_ptr -
-        (MR_TrailEntry *) MR_CONTEXT(MR_ctxt_trail_zone)->MR_zone_min;
-#else
-    return MR_trail_ptr - (MR_TrailEntry *) MR_trail_zone->MR_zone_min;
-#endif /* ! MR_THREAD_SAFE */
+    return MR_trail_ptr - MR_TRAIL_BASE;
  }

-#endif /* MR_USE_TRAIL */
+/*---------------------------------------------------------------------------*/

+void
+MR_reset_trail(void)
+{
+    MR_TrailEntry *tr_ptr;
+
+    tr_ptr = MR_trail_ptr;
+
+    while (tr_ptr != MR_TRAIL_BASE) {
+        tr_ptr--;
+        if (MR_get_trail_entry_kind(tr_ptr) == MR_func_entry) {
+            (*MR_get_trail_entry_untrail_func(tr_ptr))(
+                MR_get_trail_entry_datum(tr_ptr), MR_gc);
+        }
+    }
+
+    #if defined(MR_CONSERVATIVE_GC)
+        MR_clear_zone_for_GC(MR_TRAIL_ZONE, MR_trail_ptr);
+    #endif
+
+    MR_ticket_counter = 1;
+    MR_ticket_high_water = 1;
+}
+
+#endif /* MR_USE_TRAIL */
  /*---------------------------------------------------------------------------*/
Index: runtime/mercury_trail.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_trail.h,v
retrieving revision 1.29
diff -u -r1.29 mercury_trail.h
--- runtime/mercury_trail.h	10 Jun 2008 04:05:00 -0000	1.29
+++ runtime/mercury_trail.h	11 Jun 2008 08:33:39 -0000
@@ -192,9 +192,8 @@

      /*
      ** MR_gc:
-    ** Reserved for future use.
-    ** The interface between the trail and accurate
-    ** garbage collection is not yet designed.
+    ** A call to MR_reset_trail() was made and the entry is about to
+    ** be discarded.
      */
      MR_gc

@@ -486,7 +485,7 @@
  **
  ** Returns true iff the choicepoint indicated by `x' is newer than
  ** (i.e. was created more recently than) the choicepoint indicated by `y'.
-** The null ChoicepointId is considered older than any non-null ChoicepoindId.
+** The null ChoicepointId is considered older than any non-null ChoicepointId.
  ** If either of the choice points have been backtracked over, the behaviour
  ** is undefined.
  */
@@ -502,5 +501,14 @@
  extern MR_Unsigned
  MR_num_trail_entries(void);

+/*
+** Reset the trail.  This removes any existing entries from the trail.
+** Function trail entries are called with the MR_gc untrail reason
+** before being removed.
+** Existing non-null ChoicepointIds are no longer valid after calling
+** this function.
+*/
+extern void
+MR_reset_trail(void);

  #endif /* not MERCURY_TRAIL_H */
Index: tests/trailing/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/trailing/Mmakefile,v
retrieving revision 1.4
diff -u -r1.4 Mmakefile
--- tests/trailing/Mmakefile	17 Sep 2007 05:26:34 -0000	1.4
+++ tests/trailing/Mmakefile	11 Jun 2008 08:33:39 -0000
@@ -10,6 +10,7 @@
  	TRAIL_PROGS =			\
  		func_trail_test		\
  		func_trail_test_2	\
+		test_trail_reset	\
  		tu_test1		\
  		tu_test2
  endif
Index: tests/trailing/test_trail_reset.exp
===================================================================
RCS file: tests/trailing/test_trail_reset.exp
diff -N tests/trailing/test_trail_reset.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/trailing/test_trail_reset.exp	11 Jun 2008 08:33:39 -0000
@@ -0,0 +1,5 @@
+calling function trail entry with 11: commit
+calling function trail entry with 10: commit
+Call to test/1 succeeded
+calling function trail entry with 11: gc
+calling function trail entry with 10: gc
Index: tests/trailing/test_trail_reset.m
===================================================================
RCS file: tests/trailing/test_trail_reset.m
diff -N tests/trailing/test_trail_reset.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/trailing/test_trail_reset.m	11 Jun 2008 08:33:39 -0000
@@ -0,0 +1,79 @@
+% vim: ft=mercury ts=4 et
+:- module test_trail_reset.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module int.
+
+main(!IO) :-
+    ( test(10, _) ->
+        io.write_string("Call to test/1 succeeded\n", !IO)
+    ;
+        io.write_string("Call to test/1 failed\n", !IO)
+    ),
+    reset_trail(!IO).
+
+:- pred test(int::in, int::out) is semidet.
+
+test(X, 3) :-
+    add_trail_entry(X),
+    add_trail_entry(X + 1).
+
+:- pragma foreign_decl("C", "
+
+#include \"mercury_trail.h\"
+#include <stdio.h>
+
+extern void
+foo(void *, MR_untrail_reason);
+
+").
+
+:- pred add_trail_entry(int::in) is semidet.
+
+:- pragma foreign_proc("C",
+    add_trail_entry(X::in),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    MR_trail_function(foo, (void *) X);
+    SUCCESS_INDICATOR = MR_TRUE;
+").
+
+:- pred reset_trail(io::di, io::uo) is det.
+
+:- pragma foreign_proc("C",
+    reset_trail(IO0::di, IO::uo),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    MR_reset_trail();
+    IO = IO0;
+").
+
+:- pragma foreign_code("C", "
+
+void
+foo(void *value, MR_untrail_reason reason)
+{
+    printf(\"calling function trail entry with %ld: \",
+        (long) value);
+
+    switch (reason) {
+ 
+        case MR_commit:
+            printf(\"commit\\n\");
+            break;
+ 
+        case MR_gc:
+            printf(\"gc\\n\");
+            break;
+
+        default:
+            printf(\"unexpected trail reason\");
+    }
+}
+").

--------------------------------------------------------------------------
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