JDK-8316961 : Fallback implementations for 64-bit Atomic::{add,xchg} on 32-bit platforms
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 17,21,22
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2023-09-26
  • Updated: 2024-01-30
  • Resolved: 2023-10-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 22
22 b21Fixed
Related Reports
Blocks :  
Relates :  
Relates :  
Relates :  
Description
Currently, trying to use Atomic::add with 64-bit value/destination on 32-bit platform would fail to build with obscure linkage error, because these operations are not implemented for 32-bit platforms. This is an ongoing hassle when developing generic VM code: the 64-bit systems work well, and developers usually discover this pitfall when building/testing 32-bit builds. atomic.hpp suggests to conditionalize the caller code on supports_cx8(), but hardly anyone remembers to do it.

64-bit Atomic::cmpxchg is implemented on almost all platforms, though, which means we can write the fallback implementations for 64-bit add and xchg using 64-bit cmpxchg. When 64-bit cmpchg is not available, we can do what Access API does: take a lock.

This would simplify future development.

The caveat with such delegation would be giving up on wait-freedom that hardware implementations for xadd/xchg implicitly have. Implementing xadd/xchg with CAS loops makes them lock-free, but not wait-free. Implementing them with locks makes them not lock-free. This might not be a problem in practice. 

Existing code in this area:
 1. Fallback implementations for e.g. Unsafe::getAndAdd and Unsafe::getAndSet already do fallback CAS loops: https://github.com/openjdk/jdk/blob/1f7dfda7059f9dc14bff61b3c77d769ade85557d/src/java.base/share/classes/jdk/internal/misc/Unsafe.java#L2471-L2507
 2. Access API takes a lock: https://github.com/openjdk/jdk/blob/1f7dfda7059f9dc14bff61b3c77d769ade85557d/src/hotspot/share/oops/accessBackend.inline.hpp#L217-L253

A draft version for Atomic::add and CAS loops looks like this:
https://github.com/openjdk/jdk/compare/master...shipilev:wip-32bit-add
Comments
Changeset: ba7d08b8 Author: Aleksey Shipilev <shade@openjdk.org> Date: 2023-10-25 08:29:58 +0000 URL: https://git.openjdk.org/jdk/commit/ba7d08b8199172058bd369d880d2d6a9f9649319
25-10-2023

Thank you for implementing this!
19-10-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/16252 Date: 2023-10-18 18:58:58 +0000
18-10-2023

[~shade] this sounds perfectly reasonable. If we have 64-bit CAS then we can implement any atomic op in terms of it; else we have the existing lock mechanism to fall back on.
26-09-2023

[~dholmes], please poke the holes in this proposal, before we spend more time on it?
26-09-2023