Files
mercury/tests/trailing/test_trail_reset.m
Julien Fischer abda0be991 Provide a mechanism for resetting the trail.
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.
2008-06-13 07:27:56 +00:00

80 lines
1.4 KiB
Mathematica

% 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\");
}
}
").