[m-rev.] for review: --trace-table-io-require

Fergus Henderson fjh at cs.mu.OZ.AU
Mon Jul 22 16:07:22 AEST 2002


On 21-Jul-2002, Zoltan Somogyi <zs at cs.mu.OZ.AU> wrote:
> On 19-Jul-2002, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> > Hmm... I don't really understand the rational for these annotations.
> > What's the point of writing "tabled_for_io" annotations,
> > if they are required for all foreign_procs that do I/O?
> 
> We discussed this long ago.
> 
> The tabled_for_io annotation is an assertion that the foreign_proc may do I/O,
> but will not call Mercury code.

It is?  Ah.  This is certainly not clear from the name.
This meaning should be documented on the definition of tabled_for_io.
(Currently there are no comments on that type definition.)

> Another annotation, tabled_for_descendant_io
> (which will be introduced by a diff that I intend to send tomorrow) asserts
> that the foreign_proc will not do I/O, although it may call Mercury code
> (that may or may not do I/O). There is no provision for foreign_procs
> that both do I/O and call Mercury code, since our current mechanisms for retry
> in the debugger cannot handle a retry within such a foreign_proc correctly.
> 
> The problem is the following. Suppose predicate p is implemented using
> foreign_proc, and it calls predicates q1, ... qn, all of which are in Mercury.
> All have a pair of I/O state arguments, and suppose p does I/O between calls
> to e.g. q2 and q3. Suppose execution has progressed to the exit port of q3,
> and the user does a retry of p (the parent of q3). How do you ensure that after
> the retyry, the I/O that p did before the call to q3 will not be reexecuted,
> but the I/O that p does after the call to q3 will be executed (since it hasn't
> been executed before)? Since p is not in Mercury, the debugger cannot ensure
> this regardless of the help it gets from the compiler.

One way to do it would be to continue forward execution to the exit port
of p, and only then do the retry.  Then on retry, execution should skip
the C code for p (since it has already been executed), and only reexecute
the Mercury code that it calls (q1, ..., qn).

> > > +++ browser/dl.m	2002/07/18 05:58:23
> > > @@ -35,7 +35,7 @@
> > >  
> > >  % high-level interface to the C function dlsym().
> > >  % This version returns a higher-order predicate or function term.
> > > -% The user must use an inst cast (implemented using pragma c_code)
> > > +% The user must use an inst cast (implemented using foreign_proc)
> > >  % to cast this term to the appropriate higher-order inst before calling
> > >  % it; see dl_test.m for an example of this.
> > 
> > "foriegn_proc" is still not yet officially supported.
> > So it should be:
> > ... (implemented using pragma c_code or foreign_proc)
> 
> OK, but I thought pragma c_code is deprecated in favor of foreign_proc.
> If that isn't the case, why isn't it?

I think it is because the interface of `foreign_proc' is (or was) not
sufficiently stable.  Tyson wanted the freedom to be able to change
the interface of foreign_proc without having to worry about backward
compatibility.

I'm not sure if that is still the case... Tyson?

> > dlopen() could invoke module initializers (e.g. C++ constructors
> > for global variables) that could call Mercury code,
> > so will_not_call_mercury is not safe here.
> > 
> > Likewise for dlclose().
> 
> Actually, it looks like dlopen and dlclose both do I/O of their own (reading
> the named file) and may call Mercury code. However, since the Mercury code is
> initialization code, we should be to deal with it by turning off execution
> tracing and I/O tabling within it, thus treating dlopen and everything it calls
> as a single I/O primitive. I'll add a third annotation to cover such cases
> in my next change. I will also have to apply it to call_gcc_backend, which
> is not ideal, but is the only safe thing to do.

Hmm.  Since call_gcc_backend invokes virtually the whole of the Mercury
compiler, that would basically prevent debugging the Mercury compiler
using mdb when --target asm is specified.  So at very least execution
tracing should only be disabled in such procedures if I/O tabling is
enabled.

In the longer term, I'd like to see something along the lines of what
I wrote above.

[i.e. continue forward execution to the exit port of p, and only then
do the retry.  Then on retry, execution should skip the C code for p
(since it has already been executed), and only reexecute the Mercury
code that it calls (q1, ..., qn).]

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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