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

David Holmes davidcholmes at aapt.net.au
Mon Aug 27 18:02:00 EDT 2012


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


  Hi,


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


  Andy
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20120828/6c70d6a2/attachment.html>


More information about the Concurrency-interest mailing list