> From: Jim Blandy <xxxxxx@redhat.com>
> > http://srfi.schemers.org/srfi-50/mail-archive/msg00241.html
> See, that is interesting, though --- it shows that you don't
> have to always set up frames in Pika, if you can do all your
> computation in references owned by the calling frame.
Ok and Yup.
> > Again, it comes down to the three classes of functions, (a), (b), and
> > (c). My proposal allows people to write FFI-using code in any of
> > those three classes. If the Pika FFI includes a standard interface to
> > that auxiliary stack, then people writing FFI-using code in class (c)
> > get full interoperability with one another. But in the far more
> > common case (how many libraries do you know that permit longjmping
> > past them?), users writing FFI-using code in class (b) don't have to
> > pay for auxiliary stacks.
> But I don't even want to have to think about whether I'm going to be
> longjmped past. It's a non-local property, involving code I probably
> haven't even read, and certainly can't afford to audit each time it's
> revised. I'm willing to tolerate less-than-optimal behavior when a
> longjmp occurs, as long as it's still correct, in exchange for not
> having to think about it. And I've suggested a way to fix the
> problem: have SCM_PROTECT malloc frames, and SCM_UNPROTECT free them.
Well, you're saying (I think) that you always want all of your
calling-out functions to be in class (c) ("safe to longjmp past").
That's fine and Pika-style permits you to write that way. Pika-style
extended with a standard for the "auxiliary stack" let's you both
write that way and mix and match your code with others who do the
same.
But should the FFI spec force _all_ FFI-using functions to be in class
(c)? I hope not.
About the following: one of us is confused. Not sure which.
> > > mn_ref *
> > > mn_to_car (mn_call *call, mn_ref *ref)
> > > {
> > > mn__begin_incoherent (call);
> > > {
> > > ref->obj = check_pair (ref)->car;
> > > }
> > > mn__end_incoherent (call);
> > >
> > > return ref;
> > > }
> > Isn't that code incorrect in a threaded system? While `ref' is,
> > indeed, about to be freed, the pair that it refers to is live.
> > Assuming that the `incoherent' calls exclude only GC but not other
> > mutators (which is the benefit you seem to be claiming), then the
> > `->car' risks producing garbage.
> This is what that comment is going on about. References are
> immutable: there is no operation that changes a reference's referent.
> mn_to_car looks like a counter-example, but it isn't: officially, it
> frees REF, so it would be incorrect to call it if any other thread
> were referring to it. But since it's freeing a reference and then
> immediately allocating a new one, it might as well just reuse the
> reference.
That's not what I mean by "incorrect in a threaded system".
Am I correct that `check_pair (ref)' returns a pointer to something
like:
struct pair
{
scheme_value car;
scheme_value cdr;
}
?
And am I correct that mn__begin_incoherent excludes GC but not other
mutators? If it excludes _all_ mutators then I don't think you really
have much savings in `to_car' compared to `car': you're saving the
allocation of a new handle, sure, but that should be very, very cheap
compared to `mn__begin_incoherent' and `mn__end_incoherent'.
If both assumptions are true then the code is incorrect because
`->car' is not necessarily going to return a legitimate scheme value
(it may return a "half written" one).
If the second assumption (about excluding only GC) is false -- then I
don't see a substantial savings here: you need to acquire a highly
contentious lock.
If the first assumption is false (about returning a pointer to a pair)
-- then I don't know what the heck that code means.
> Well, if you'll grant that this is fuzzy talk:
> Pika's ooze is that you appear to be operating on local variables, but
> you can only use them as lvalues, never rvalues. And they're actually
> data structures owned by the GC; rather than being managed by the
> compiler, as local variables are, they have to be explicitly
> registered and unregistered. That's the source of the longjmp
> problems, too.
Ok.
-t