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

Tom Lord <lord@xxxxxxx> writes:
> 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 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).

That's right, in theory.

(Just to be clear: we're now talking about details of the Minor
implementation, here, not whether the Minor API can be implemented
properly.  I think we agree that the Minor interface gives
implementations the hooks they need to do whatever synchronization is

I just assume things will work out here:

- The Minor implementation is not intended to be portable to all ISO C
  / POSIX platforms.  I'm much more interested in the native code JIT
  than in the interpreter, so the Minor implementation will generally
  make machine-specific assumptions where doing so makes a big
  difference.  And since I'm interested in clean interoperation with
  the C and C++ toolchains, I plan to generate native .o files, so
  Minor will be ABI-specific, too.

- Java requires that pointers not be corrupted, even in the absence of
  proper synchronization.  As far as I can see, the gcj front end for
  GCC doesn't do anything special to ensure that pointers are read and
  written with single instructions.  So I think C code should be able
  to make the same assumption.

- GCC must not generate split stores for sig_atomic_t, and the GNU C
  library simply defines that as 'int' on every platform.  So on those
  platforms where int can hold a pointer, I'm fine.  This is true on
  every platform I intend to care about, except the x86-64.

- Of course, the instructions the compiler generates don't dictate how
  the inter-processor cache interactions work, so in theory they could
  chop up the pointer, too.  But Java already requires that writes to
  words appear atomic, so this is apparently not a problem.