RFR: 8186476: Generalize Atomic::add with templates

Kim Barrett kim.barrett at oracle.com
Sun Aug 20 06:16:30 UTC 2017

Please review this change to Atomic::add, making it a function
template with a per-platform underlying implementation.

This change is similar to 8186166: "Generalize Atomic::cmpxchg with
templates", with similar goals and taking a similar approach.

This change deprecates add_ptr.  Followup changes will convert
existing uses of cmpxchg_ptr and eventually remove it.  Followup
changes will also update uses of cmpxchg that can be simplified
because of the generalized API.  Only changes to usage that were
required by the new implementation have been made so far.

The add function calls private Atomic::AddImpl, to select among
several cases, based on the argument types.  Each case performs some
checking and possibly conversion to reach a standard form of the
arguments (or fail and report a compile time error), which are then
passed to private Atomic::PlatformAdd.

Only safe conversions of the first (add_value) argument are made by
the AddImpl layer.  add_value must be integral, and is never narrowed.
dest's value type must be either integral or a pointer type.  When
both are integral, they must be of the same signedness.  If smaller,
add_value will be promited to the same size as dest's value type.

The PlatformAdd class is provided by each platform, and performs
additional case analysis to generate the appropriate code for the
platform.  Most PlatformAdd implementations use one of two helper base
classes, Atomic::FetchAndAdd and Atomic::AddAndFetch.  These provide
common parts of the implementation in terms of a support function
provided by the derived PlatformAdd, accessed using CRTP.

This change involves modifications to all of the existing platform
implementations of Atomic::add.  I've updated all of the platforms,
but only tested those supported by Oracle.  I'll need help from the
various platform maintainers to check and test my changes.

Changes to files can be categorized as follows:

[No new metaprogramming tools!]

Change add to a template:

Oracle-supported platforms:
atomic_bsd_x86.hpp - 64bit only

Non-Oracle platform changes:
atomic_bsd_x86.hpp - 32bit

Usage changes required by API change:

A few specific items:

- atomic_linux_arm.hpp

Neither add variant has "cc" in the clobbers list, even though the
condition codes are modified.  That seems like a pre-existing bug.

- atomic_linux_sparc.hpp

Neither add variant has "cc" in the clobbers list, even though the
condition codes are modified.  That seems like a pre-existing bug.

The 32-bit add was using intptr_t as the rv type.  Probably a harmless
copy-paste mistake.  Now using template parameter type.

Uses hard-coded machine registers and assumes the inline-asm
processing assigns the values to the corresponding machine registers,
even though the given constraints are just generic register requests.
I don't understand how this can work.

- atomic_solaris_sparc.hpp

Atomic::add was implemented using asm code in solaris_sparc.il.  I was
going to change it to use gcc-style inline-asm, but the linux_sparc
version wasn't helpful this time (unlike for cmpxchg) (see above).
Instead, I wrote the CAS-loop in C++, using Atomic::cmpxchg; much
simpler code, and should be no less efficient, assuming the compiler
does it's job.



Ad hoc hotspot nightly test.

More information about the hotspot-dev mailing list