Re: Comparing Pika-syle and JNI-style Jim Blandy 14 Jan 2004 23:54 UTC
Tom Lord <xxxxxx@emf.net> 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; > } > > ? Yes. > And am I correct that mn__begin_incoherent excludes GC but not other > mutators? Yes. > 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 needed.) 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.