[concurrency-interest] jni effectively immutable "constructor"guarded by java volatile for safe publishing

Boehm, Hans hans.boehm at hp.com
Mon Aug 27 18:18:37 EDT 2012

Some of us have definitely considered it a goal to ensure that Java, C, and C++ synchronization works together as expected, with Java synchronization providing the right visibility guarantees for C or C++ variables, and conversely.  In particular mixed language data-race-free programs should still be sequentially consistent unless you say otherwise.  I agree with David, that in a case like this, extremely unlikely to encounter problems, but there is no written guarantee of that.  In more esoteric cases (e.g. the often cited IRIW example, where one variable is a Java volatile variable, and the other a C++ atomic variable, accessed in native code), having the interaction work correctly requires that choices made by the C ABI are consistent with the choices made by JVM implementers.  I suspect that in some cases we're not there yet when it comes to these esoteric cases.  But that's unlikely to create practical problems.


From: concurrency-interest-bounces at cs.oswego.edu [mailto:concurrency-interest-bounces at cs.oswego.edu] On Behalf Of David Holmes
Sent: Monday, August 27, 2012 3:02 PM
To: Andy Nuss; concurrency-interest at cs.oswego.edu
Subject: Re: [concurrency-interest] jni effectively immutable "constructor"guarded by java volatile for safe publishing

Hi Andy,

I don't think the JMM guarantees extend to anything outside the Java heap - or more specifically it only applies to Java fields. In practice the barriers/fences used today are coarse-grained and will affect all memory equally (assuming you aren't using native mapping techniques to place shared buffers in special memory locations!). In addition the transitions to/from native code require their own barriers/fences to ensure the thread and the VM have a consistent view of each other - this is the case in hotspot. Your use of volatiles at the Java level then introduces additional happens-before ordering. So I'd say that in practice this will work fine (as long as you are using normal process memory), but nothing is guaranteeing you that.

To your second question, it is fine, in hotspot at least, to use native synchronization objects, and you can call back into Java with no problem. The usual caveat is that you are responsible for ensuring there are no deadlocks introduced. This assumes regular Java code calling native methods and the native methods using regular JNI calls to invoke Java methods. Things can get problematic if you use (JVMTI) agents but for regular Java/native code there are no special issues.

David Holmes
-----Original Message-----
From: concurrency-interest-bounces at cs.oswego.edu [mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of Andy Nuss
Sent: Tuesday, 28 August 2012 3:17 AM
To: concurrency-interest at cs.oswego.edu
Subject: [concurrency-interest] jni effectively immutable "constructor"guarded by java volatile for safe publishing

1) I have a native function which passes several params and uses a native C++ constructor in-place constructor relative to a saved nio direct bytebuffer to create an object,  returning a long which is cast from the pointer to object.  This object's constructed values are effectively immutable in that only that native call sets the members of the obect.  The C++ object then can do work based on its constructed state.

2) java code that makes the above calls safely publishes the longified version of the C++ pointer (created above) somewhere (without mutex) and changes a volatile variable to hopefully publish the memory changes made in the "constructor" above to other threads.

Now another java thread reads that volatile fence variable of 2), and then picks up that published long, and calls another native function that accesses that effectively immutable object in the C++ memory space to do some work.

Is that other thread guaranteed to see the fully constructed native object because of the Java Memory Model guarantees about volatiles and fences?  I would bet the answer is yes on some platforms, but I see that different chips work different ways with using fences, and was wondering about all platforms for which java is available.  I couldn't tell by googling whether the Java Memory Model made guarantees relative to changes in *all* memory, not just that of the virtual machine.  Maybe sun.misc.Unsafe might come to the rescue?

(By the way, I need to use mutexes in my native code too for the purpose of subdividing the nio bytebuffer of 1), and found that JNI MontorEnter() was extraordinarily slow, as are all callbacks into java code.  I saw somewhere that it is safe to use POSIX threads' or Windows threads' semaphores as long as during the critical section, there are no callbacks into jvm.  But I wonder if anyone can answer this other question?)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20120827/ac5ad5ca/attachment-0001.html>

More information about the Concurrency-interest mailing list