Do Java Atomics only require atomicity with respect to the VM
Asked Answered
C

2

6

I was looking at the Java source code for the AtomicInteger class (found here) to see which atomic primitives are required to implement a JVM. I noticed they use the undocumented Unsafe API to implement their atomic integer operations and that the only two primitives they use seem to be the compare and swap and compare and set operations. And the Unsafe class implements these instructions as native methods which leads me to believe they are using the native instructions which perform these primitive operations in the general case. However, not every processor(though most modern ones do) has an instruction set which supports these primitives natively. Now even without native processor support those primitives could be implemented by the VM in a way that guarantees atomicity with other VM threads, but not necessarily with other native threads. So does java require these primitives on the native architecture to have a valid JVM and thus all JVM implementations would support atomicity with native threads, or is the atomicity in java only guaranteed between java threads?

Cleavage answered 6/5, 2015 at 14:0 Comment(5)
I would make this an answer but I can't find the links anymore. The group that implements the JVM on each architecture determines the code. If the architecture supports atomic instructions, then that is what is used. If not then the code emulates those atomic instructions. It could be CAS or LL/SC or simulated code. If I find those links I post more.Farthingale
@Farthingale well if the support for atomicity with native threads is dependant on the architecture then it is not guaranteed by the JVM specification then correct? Which is to say a JVM implemented on an architecture which did not support those instructions(or the ability to reproduce the effect of those instructions) would still be a valid JVM.Cleavage
Which platforms that don't have atomic instructions has the JVM been ported to? I'm not aware of anyGregorio
@Gregorio i haven't seen any yet, although possibly some smart card/SIM Card implementations which have a JVM may. I guess my question phrased in another way would be is it possible to create a valid JVM on such an architecture, not whether or not it has been done.Cleavage
I would guess that smart cards are single-threaded, so you probably don't need any special instructions for most atomic operations, only CAS might need a special instruction or a way to prevent context switches in the critical section.Gregorio
C
2

The JNI does not provide any way for a native thread to get the address of a Java variable. All access to the variable, whether from Java bytecode or from a native thread, must go through JVM machinery. So your question really is moot.

Java atomics "require atomicity with respect to the JVM", and "with respect to the JVM" is the only case that matters.

Corder answered 6/5, 2015 at 16:16 Comment(3)
thanks, i guess i wasn't thinking about how you would get a handle to the data from native code, but the only way that doesn't violate the JVM is through JNI and JNI would be required to modify all atomic values anyways.Cleavage
In theory yes, in practice using memory-mapped buffers + Unsafe can be relevant, but if you do that you're basically moving outside the JVM spec. Though that might change with the JMM changes that are scheduled for java9Gregorio
@Gregorio right depending on the VM implementation you are using, you could probably figure out the address of the JVM heap and get the actual location in memory of any particular variable but then you have violated the VM spec and nothing in the specification is guaranteed to work.Cleavage
F
2

The only known OS that do not support CAS or LL/SC are The SPARC 32 and PA-RISC. As documented in the JSR-133 Cookbook (go to the Multiprocessors section), the resolution for this is to build from ldcw. Which is stated as

The only atomic primitive on pa-risc is ldcw, a form of test-and-set, from which you would need to build up atomic conditional updates using techniques such as those in the HP white paper on spinlocks.

http://h21007.www2.hp.com/portal/download/files/unprot/itanium/spinlocks.pdf

Also some information on futexes

https://parisc.wiki.kernel.org/index.php/FutexImplementation

Flavoring answered 6/5, 2015 at 15:34 Comment(1)
Ok, that is some interesting information on those specific implementations, but it didn't really answer my question which is whether or not it violates the JVM specification to implement a JVM where the atomic operations are not guarenteed to be atomic to native threads but are guarenteed to be atomic for JVM threads.Cleavage
C
2

The JNI does not provide any way for a native thread to get the address of a Java variable. All access to the variable, whether from Java bytecode or from a native thread, must go through JVM machinery. So your question really is moot.

Java atomics "require atomicity with respect to the JVM", and "with respect to the JVM" is the only case that matters.

Corder answered 6/5, 2015 at 16:16 Comment(3)
thanks, i guess i wasn't thinking about how you would get a handle to the data from native code, but the only way that doesn't violate the JVM is through JNI and JNI would be required to modify all atomic values anyways.Cleavage
In theory yes, in practice using memory-mapped buffers + Unsafe can be relevant, but if you do that you're basically moving outside the JVM spec. Though that might change with the JMM changes that are scheduled for java9Gregorio
@Gregorio right depending on the VM implementation you are using, you could probably figure out the address of the JVM heap and get the actual location in memory of any particular variable but then you have violated the VM spec and nothing in the specification is guaranteed to work.Cleavage

© 2022 - 2024 — McMap. All rights reserved.