[m-dev.] Add an bool argument to filter
Erwan Jahier
Erwan.Jahier at irisa.fr
Fri Oct 29 19:47:18 AEST 1999
Estimated hours taken: 2
This change implements the Fergus suggestion; i.e. add an argument to filter
that returns a bool saying whether we stop collecting or not.
trace/mercury_trace_external.c:
Opium-M/source/collect.in:
Opium-M/source/collect.op:
Add an new argument to filter that says saying whether we stop
collecting or not.
Opium-M/source/collect.op:
Also improve the documentation by describing the event type.
Index: 0.4/mercury_trace_external.c
--- 0.4/mercury_trace_external.c Fri, 29 Oct 1999 09:00:28 +0200 jahier (collect/3_mercury_tr 1.3 640)
+++ 0.4(w)/mercury_trace_external.c Fri, 29 Oct 1999 11:41:39 +0200 jahier (collect/3_mercury_tr 1.3 640)
@@ -183,9 +183,10 @@
static void MR_trace_browse_one_external(MR_Var_Spec which_var);
static void MR_COLLECT_filter(Word (*filter_ptr)(Integer, Integer, Integer,
Word, Word, String, String, String, Integer, Integer,
- Integer, String, Word, Word *), Unsigned seqno,
+ Integer, String, Word, Word *, Char *), Unsigned seqno,
Unsigned depth, MR_Trace_Port port,
- const MR_Stack_Layout_Label *layout, const char *path);
+ const MR_Stack_Layout_Label *layout, const char *path,
+ bool *stop_collecting);
#if 0
This pseudocode should go in the debugger process:
@@ -462,8 +463,10 @@
static void (*initialize_ptr)(Word *) = NULL;
static Word (*filter_ptr)(Integer, Integer, Integer, MR_Trace_Port,
MR_PredFunc, String, String, String, Integer,
- Integer, Integer, String, Word, Word *) = NULL;
+ Integer, Integer, String, Word, Word *,
+ Char *) = NULL;
static bool collect_linked = FALSE;
+ static bool stop_collecting = FALSE;
Integer debugger_request_type;
Integer live_var_number;
Word debugger_request;
@@ -536,9 +539,21 @@
(Unsigned) depth,
(MR_Trace_Port) port,
layout,
- path);
- goto done;
+ path,
+ &stop_collecting);
+ if (stop_collecting) {
+ (*send_collect_result_ptr)(
+ (Word) MR_collecting_variable,
+ (Word) &MR_debugger_socket_out);
+ external_debugger_mode = MR_reading_request;
+ #if defined(HAVE_DLFCN_H)&&defined(HAVE_DLCLOSE)
+ dlclose((void *)handle);
+ #endif
+ break;
+ } else {
+ goto done;
+ }
case MR_reading_request:
break;
@@ -822,9 +837,24 @@
(Unsigned) depth,
(MR_Trace_Port) port,
layout,
- path);
+ path,
+ &stop_collecting);
- goto done;
+ if (stop_collecting) {
+ (*send_collect_result_ptr)(
+ (Word)
+ MR_collecting_variable,
+ (Word)
+ &MR_debugger_socket_out);
+ external_debugger_mode =
+ MR_reading_request;
+#if defined(HAVE_DLFCN_H)&&defined(HAVE_DLCLOSE)
+ dlclose((void *)handle);
+#endif
+ break;
+ } else {
+ goto done;
+ }
} else {
MR_send_message_to_socket(
"collect_not_linked");
@@ -1439,10 +1469,13 @@
*/
static void
MR_COLLECT_filter(Word (*filter_ptr)(Integer, Integer, Integer, Word, Word,
- String, String, String, Integer, Integer, Integer, String, Word, Word *),
+ String, String, String, Integer, Integer, Integer, String, Word, Word *,
+ Char *),
Unsigned seqno, Unsigned depth, MR_Trace_Port port,
- const MR_Stack_Layout_Label *layout, const char *path)
-{
+ const MR_Stack_Layout_Label *layout, const char *path,
+ bool *stop_collecting)
+{
+ Char result;
MR_TRACE_CALL_MERCURY((*filter_ptr)(
MR_trace_event_number,
seqno,
@@ -1457,7 +1490,9 @@
layout->MR_sll_entry->MR_sle_detism,
(String) path,
MR_collecting_variable,
- &MR_collecting_variable));
+ &MR_collecting_variable,
+ &result));
+ *stop_collecting = (result == 'y');
}
#endif /* MR_USE_EXTERNAL_DEBUGGER */
--- collect.op.save Fri Oct 29 11:20:24 1999
+++ collect.op Fri Oct 29 11:24:15 1999
@@ -9,7 +9,7 @@
% There are several things to do in order to be able to execute a
% collect/1 command:
% 1) create a file that will that contain the definition of collected_type,
-% initialize/1 and filter/3,
+% initialize/1 and filter/4,
% 2) generate `collect.m' from this file (generate_collect/1),
% 3) compile collect.m (compile_collect/0),
% 4) dynamically link it with the current execution (dyn_link_collect/0).
@@ -30,51 +30,108 @@
variable that will contain the result of the monitoring\n\
activity.\n\
(2) The predicate initialize/1 which initializes this \n\
- collecting variable. initialize/1 have the \n\
+ collecting variable. initialize/1 should follow the \n\
following declarations:\n\
:- pred initialize(collected_type).\n\
:- mode initialize(out) is det.\n\
- (3) the predicate filter/3 which updates it at each execution \n\
- event. filter/3 should have the following declarations:\n\
- :- pred filter(event, collected_type, collected_type).\n\
- :- mode filter(in, acc_in, acc_out) is det.\n\
+ (3) the predicate filter/4 which updates it at each execution \n\
+ event. filter/4 also outputs a bool that indicates whether to stop\
+ collecting. If this bool is always set to `no', the collecting will\
+ process until the last event is reached. filter/4 should follow the \
+ following declarations:\n\
+ :- pred filter(event, collected_type, collected_type, bool).\n\
+ :- mode filter(in, acc_in, acc_out, out) is det.\n\
where `acc_in' and `acc_out' have `in' and `out' respectively\n\
as default values.\n\
(4) and optionally the mode definition of `acc_in' and `acc_out'\n\
in one want to override their default values.\n\
\n\
+The event type is defined as follows (for more detail about the meaning of \
+each event attributes, please refer to the Reference Manual):\n\
+\n\
+:- type event ---> \n\
+ event(\n\
+ event_number,\n\
+ call_number,\n\
+ depth_number,\n\
+ trace_port_type,\n\
+ pred_or_func,\n\
+ declarated_module_name,\n\
+ defined_module_name, \n\
+ proc_name,\n\
+ arity,\n\
+ mode_number,\n\
+ determinism,\n\
+ goal_path_string).\n\
+\n\
+:- type event_number == int.\n\
+:- type call_number == int.\n\
+:- type depth_number == int.\n\
+:- type trace_port_type\n\
+ ---> call\n\
+ ; exit\n\
+ ; redo\n\
+ ; fail\n\
+ ; ite_cond\n\
+ ; ite_then\n\
+ ; ite_else\n\
+ ; neg_enter\n\
+ ; neg_success\n\
+ ; neg_failure\n\
+ ; disj\n\
+ ; switch\n\
+ ; nondet_pragma_first\n\
+ ; nondet_pragma_later\n\
+ ; exception.\n\
+:- type pred_or_func\n\
+ ---> predicate\n\
+ ; function.\n\
+:- type declarated_module_name == string.\n\
+:- type defined_module_name == string.\n\
+:- type proc_name == string.\n\
+:- type arity == int.\n\
+:- type mode_number == int.\n\
+:- type determinism == int. \n\
+:- type goal_path_string == string.\n\
+:- type procedure ---> proc(\n\
+ pred_or_func, \n\
+ declarated_module_name, \n\
+ proc_name, \n\
+ arity, \n\
+ mode_number).\n\
+\n\
+Here are functions that eases the access of the event attributes:\n\
+\n\
+:- func chrono(event::in) = (event_number::out) is det.\n\
+:- func call(event::in) = (call_number::out) is det.\n\
+:- func depth(event::in) = (depth_number::out) is det.\n\
+:- func port(event::in) = (trace_port_type::out) is det.\n\
+:- func proc_type(event::in) = (pred_or_func::out) is det.\n\
+:- func decl_module(event::in) = (declarated_module_name::out) is det.\n\
+:- func def_module(event::in) = (defined_module_name::out) is det.\n\
+:- func proc_name(event::in) = (proc_name::out) is det.\n\
+:- func proc_arity(event::in) = (arity::out) is det.\n\
+:- func proc_mode_number(event::in) = (mode_number::out) is det.\n\
+:- func proc(event::in) = (procedure::out) is det.\n\
+:- func determinism(event::in) = (determinism::out) is det.\n\
+:- func goal_path(event::in) = (goal_path_string::out) is det.\n\
+\n\
+\n\
Then, this file is used to generate the Mercury module `collect.m', \
which is compiled and dynamically linked with the current execution. \
When a `collect' request is made from the external debugger, a variable \
of type collected_type is first initialized (with initialize/1) and \
-then updated (with filter/3) for all the events of the remaining \
-execution. When the end of the execution is reached, the last value of \
+then updated (with filter/4) for all the events of the remaining \
+execution. When the fourth argument of filter is equal to yes, or when \
+the end of the execution is reached, the last value of \
the collecting variable is send to Opium-M.\n\
\n\
-collect/2 can be specified by the following pseudo Opium-M code: \n\
-` collect_spec(File, Result) :-\n\
- generate_collect(File),\n\
- compile_collect,\n\
- dyn_link_collect,\n\
- get_event_list(EventList),\n\
- initialize(Start),\n\
- foldl(filter, EventList, Start, Result).\n\
-'\n\
-where: \n\
- *) generate_collect/1 generates from `File' the Mercury module \
-`collect.m'; \n\
- *) compile_collect/0 compiles `collect.m' (generating `File.so'); \n\
- *) dynamically_link_collect/0 links the corresponding object file \n\
-(`File.so') with the current program execution; \n\
- *) get_event_list/1 collects in a list all the events from the current \
-event until the end of the execution; \n\
- *) foldl/4 is the classical fold predicate operating left-to-right. \n\
- \n\
-collect/2 does the same thing as collect_spec/2 except it operates \
-on the fly without creating any list of events."
+collect/2 can be seen as fold/4 meta-predicate except that (1) the \
+initialization and the updating of the accumulator is done via Mercury \
+predicates defined in a separate file (2) it does not take a list as \
+argument but operates on the fly on a list of events."
).
-
%------------------------------------------------------------------------------%
opium_command(
name : collect,
@@ -87,7 +144,7 @@
parameters : [],
message :
"If File contains the implementation of the Mercury predicates initialize/1 \
-and filter/3, collect(File, Result) calls filter/3 with each event of the \
+and filter/4, collect(File, Result) calls filter/4 with each event of the \
execution and an accumulator initialized by initialize/1, and returns the \
final value in Result.\n\
\n\
@@ -99,7 +156,7 @@
\n\
initialize(0).\n\
\n\
- filter(Event, AccIn, AccOut) :-\n\
+ filter(Event, AccIn, AccOut, no) :-\n\
( port(Event) = call ->\n\
AccOut = AccIn + 1\n\
;\n\
@@ -207,7 +264,7 @@
message :
"Generates a Mercury module named `collect.m' from file File; File should \
contain the definition of the accumulator type (collected_type), \
-initialize/1 and filter/3 predicates."
+initialize/1 and filter/4 predicates."
).
generate_collect_Op(File) :-
--- collect.in.save Fri Oct 29 11:30:00 1999
+++ collect.in Fri Oct 29 11:28:48 1999
@@ -1,6 +1,7 @@
:- module collect.
:- interface.
+:- import_module char.
:- type collected_type.
@@ -11,9 +12,9 @@
:- pred filter(event_number, call_number, depth_number, trace_port_type,
pred_or_func, declarated_module_name, defined_module_name, proc_name,
arity, mode_number, determinism, goal_path_string, collected_type,
- collected_type).
+ collected_type, char).
-:- mode filter(in, in, in, in, in, in, in, in, in, in, in, in, acc_in, acc_out)
+:- mode filter(in, in, in, in, in, in, in, in, in, in, in, in, acc_in, acc_out,out)
is det.
:- pred send_collect_result(collected_type, io__output_stream, io__state,
@@ -25,11 +26,11 @@
:- pragma export(initialize(out), "ML_COLLECT_initialize").
:- pragma export(filter(in, in, in, in, in, in, in, in, in, in, in, in,
- acc_in, acc_out), "ML_COLLECT_filter").
+ acc_in, acc_out, out), "ML_COLLECT_filter").
:- pragma export(send_collect_result(in, in, di, uo),
"ML_COLLECT_send_collect_result").
-:- import_module int, io.
+:- import_module bool, int, io.
:- type event_number == int.
:- type call_number == int.
@@ -153,9 +154,9 @@
proc_mode_number(Event) = ModeNumber :-
Event = event(_, _, _, _, _, _, _, _, _, ModeNumber, _, _).
-% proc(Event) = (proc(ProcType, DeclModule, Name, Arity, ModeNum)) :-
-% Event = event(_, _, _, ProcType, DeclModule, _, _, Name, Arity,
-% ModeNum, _, _).
+proc(Event) = (proc(ProcType, DeclModule, Name, Arity, ModeNum)) :-
+ Event = event(_, _, _, _, ProcType, DeclModule, _, Name, Arity,
+ ModeNum, _, _).
determinism(Event) = Determinism :-
Event = event(_, _, _, _, _, _, _, _, _, _, Determinism, _).
@@ -166,10 +167,17 @@
filter(EventNumber, CallNumber, DepthNumber, Port, PredOrFunc, DeclModuleName,
DefModuleName, PredName, Arity, ModeNum, Determinism, Path,
- AccIn, AccOut) :-
+ AccIn, AccOut, StopChar) :-
filter(event(EventNumber, CallNumber, DepthNumber, Port, PredOrFunc,
DeclModuleName, DefModuleName, PredName, Arity, ModeNum,
- Determinism, Path), AccIn, AccOut).
+ Determinism, Path), AccIn, AccOut, Stop),
+ (
+ Stop = no,
+ StopChar = 'n'
+ ;
+ Stop = yes,
+ StopChar = 'y'
+ ).
% This predicate is called at the end of the collect execution to sent the
@@ -183,6 +191,6 @@
:- type collect_result --->
collected(collected_type).
-:- pred filter(event, collected_type, collected_type).
-:- mode filter(in, acc_in, acc_out) is det.
-:- pragma inline(filter/3).
+:- pred filter(event, collected_type, collected_type, bool).
+:- mode filter(in, acc_in, acc_out, out) is det.
+:- pragma inline(filter/4).
--
R1.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list