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