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?
Atomicity. Atomic operations are those operations that ALWAYS execute together. Either all of them execute together, or none of them executes. If an operation is atomic, then it cannot be partially complete, either it will be complete, or not start at all, but will not be incomplete.
The most commonly used atomic variable classes in Java are AtomicInteger, AtomicLong, AtomicBoolean, and AtomicReference. These classes represent an int, long, boolean, and object reference respectively which can be atomically updated.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With