[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Comparing Pika-syle and JNI-style

This page is part of the web mail archives of SRFI 50 from before July 7th, 2015. The new archives for SRFI 50 contain all messages, not just those from before July 7th, 2015.





    > From: Jim Blandy <jimb@xxxxxxxxxx>


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