Adding in porters-dev

On 25/10/2023 5:12 pm, David Holmes wrote:
From  https://bugs.openjdk.org/browse/JDK-8318776

Regardless of platform size (32-bit or 64-bit) the Java language has always required that the underlying platform (or the VM) provides a means of performing atomic load and store of 64-bit values, for volatile long and double support.

Since Java 5 the java.util.concurrent.atomic package introduced APIs that provide a range of atomic operations, the most fundamental being a compare-and-swap (CAS), also known as a compare-exchange, out of which other atomic operations can be constructed if there is no direct platform support. This capability was later extended to the VarHandle API as well.

While all platforms needed a mechanism for 64-bit load and store, not all platforms support a 64-bit CAS, internally known as cmpxchg8. To address that the supports_cx8 flag was introduced so that on platforms without cmpxchg8 native support, it could be emulated via other techniques e.g. locking. (Note this is not without its own issues as all accesses to the field must be done in a way that is consistent with the use of locking by cmpxchg8 - word-tearing is a real risk).

Internal to the VM we also have use of lock-free algorithms and atomic operations, with the latter defined via atomic.hpp. Originally in that code we needed to check supports_cx8 for platforms without 64-bit support, but in practice we tended to avoid using 64-bit fields in such cases so we could avoid the complexity of introducing lock-based emulation.

Unfortunately, when the atomic interface in the VM was templatized and redesigned, it appears that the fact cmpxchg8 may not be available was overlooked and supports_cx8 is not consulted. Consequently if someone introduced an atomic operation on a 64-bit field they would get a linkage error on platforms without cmpxchg8 - so again if this happened we tended to back away from using a 64-bit field.

Along the way the access API in the VM was introduced, which also provided atomic ops on oops and did consult supports_cx8 with a lock-based fallback.

We have now reached a point where there are cases where we do want 64-bit atomic operations but we don't want the complexity of dealing with platforms that don't support it. So we want to require that supports_cx8 always be assumed true (the VM could abort at runtime if run on a platform where it is not true) and we can then proceed with 64-bit atomics in the VM and also remove all the lock-based fallbacks in the access API and in the Java APIs.

The OpenJDK has limited support for 32-bit platforms these days: PPC32 was dropped a long time ago; Windows 32-bit is now a deprecated port (but supports cmpxchg8 anyway); leaving only ARM32 as a platform of potential concern. But even then we support cmpxchg8 in all known modern implementations, as described in os_cpu/linux_arm/atomic_linux_arm.hpp:

/*
  * Atomic long operations on 32-bit ARM
 * ARM v7 supports LDREXD/STREXD synchronization instructions so no problem.
  * ARM < v7 does not have explicit 64 atomic load/store capability.
  * However, gcc emits LDRD/STRD instructions on v5te and LDM/STM on v5t
  * when loading/storing 64 bits.
  * For non-MP machines (which is all we support for ARM < v7)
  * under current Linux distros these instructions appear atomic.
  * See section A3.5.3 of ARM Architecture Reference Manual for ARM v7.
  * Also, for cmpxchg64, if ARM < v7 we check for cmpxchg64 support in the
  * Linux kernel using _kuser_helper_version. See entry-armv.S in the Linux
  * kernel source or kernel_user_helpers.txt in Linux Doc.
  */

So the practical reality is that we do not expect to encounter any mainstream OpenJDK platform where we don't in fact have support for cmpxchg8.

-------

Before I proceed with this does anyone have any strong and reasonable objections? Is there some platform support aspect that has been overlooked?

Note the JDK part could be (probably should be) done as a follow up RFE to simplify the review and approval process.

Thanks,
David

Reply via email to