[aarch64-port-dev ] RFR: aarch64: minor improvements of atomic operations
Yangfei (Felix)
felix.yang at huawei.com
Wed Nov 13 08:36:41 UTC 2019
> -----Original Message-----
> From: Yangfei (Felix)
> Sent: Wednesday, November 13, 2019 10:36 AM
> To: 'Andrew Haley' <aph at redhat.com>; Erik Österlund
> <erik.osterlund at oracle.com>; Andrew Dinn <adinn at redhat.com>;
> aarch64-port-dev at openjdk.java.net
> Cc: hotspot-dev at openjdk.java.net
> Subject: RE: [aarch64-port-dev ] RFR: aarch64: minor improvements of atomic
> operations
>
> > -----Original Message-----
> > From: Andrew Haley [mailto:aph at redhat.com]
> > Sent: Wednesday, November 13, 2019 3:00 AM
> > To: Erik Österlund <erik.osterlund at oracle.com>; Yangfei (Felix)
> > <felix.yang at huawei.com>; Andrew Dinn <adinn at redhat.com>;
> > aarch64-port-dev at openjdk.java.net
> > Cc: hotspot-dev at openjdk.java.net
> > Subject: Re: [aarch64-port-dev ] RFR: aarch64: minor improvements of
> > atomic operations
> >
> > On 11/12/19 5:38 PM, Erik Österlund wrote:
> > > My hope is that the AArch64 port should use inline assembly as you
> > > suggest,
> > so we can see that the generated code is correct, as we wait for the
> > glorious future where all HotSpot code has been rewritten to work with
> > seq_cst (and we are *not* there now).
> >
> > I don't doubt it. :-)
> >
> > But my arguments about the C++ intrinsics being well-enough defined,
> > at least on AArch64 Linux, have not changed, and I'm not going to argue all
> that again.
> > I'll grant you that there may well be issues on various x86 compilers,
> > but that isn't relevant here.
>
> Looks like I reignited an old discussion :- )
>
> > > Now it looks like you have discovered that we sometimes have double
> > > trailing dmb ish, and sometimes lacking leading dmb ish if I am
> > > reading this right. That seems to make the case stronger,
> >
> > Sure, we can use inline asm if there's no other way to do it, but I
> > don't think that's necessary. All we need is to use
> >
> > T res;
> > __atomic_exchange(dest, &exchange_value, &res, __ATOMIC_RELEASE);
> > FULL_MEM_BARRIER;
> >
>
> When we go the C++ intrinsics way, we should also handle
> Atomic::PlatformCmpxchg.
> When I compile the following function with GCC 4.9.3:
>
> long foo(long exchange_value, long volatile* dest, long compare_value) {
> long val = __sync_val_compare_and_swap(dest, compare_value,
> exchange_value);
> return val;
> }
>
> I got:
>
> .L2:
> ldaxr x0, [x1]
> cmp x0, x2
> bne .L3
> stlxr w4, x3, [x1]
> cbnz w4, .L2
> .L3:
>
>
> Proposed patch:
> diff -r 846fee5ea75e
> src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp
> --- a/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp Wed Nov 13
> 10:27:06 2019 +0900
> +++ b/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp Wed Nov
> +++ 13 10:14:58 2019 +0800
> @@ -52,7 +52,7 @@
> T volatile*
> dest,
>
> atomic_memory_order order) const {
> STATIC_ASSERT(byte_size == sizeof(T));
> - T res = __sync_lock_test_and_set(dest, exchange_value);
> + T res = __atomic_exchange_n(dest, exchange_value, __ATOMIC_RELEASE);
> FULL_MEM_BARRIER;
> return res;
> }
> @@ -70,7 +70,11 @@
> __ATOMIC_RELAXED,
> __ATOMIC_RELAXED);
> return value;
> } else {
> - return __sync_val_compare_and_swap(dest, compare_value,
> exchange_value);
> + T value = compare_value;
> + __atomic_compare_exchange(dest, &value, &exchange_value,
> /*weak*/false,
> + __ATOMIC_RELEASE,
> __ATOMIC_RELAXED);
> + FULL_MEM_BARRIER;
> + return value;
> }
> }
Still not strong enough? considering the first of ldxr of the loop may be speculated.
v2 patch:
diff -r 846fee5ea75e src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp
--- a/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp Wed Nov 13 10:27:06 2019 +0900
+++ b/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp Wed Nov 13 16:33:16 2019 +0800
@@ -52,7 +52,7 @@
T volatile* dest,
atomic_memory_order order) const {
STATIC_ASSERT(byte_size == sizeof(T));
- T res = __sync_lock_test_and_set(dest, exchange_value);
+ T res = __atomic_exchange_n(dest, exchange_value, __ATOMIC_RELEASE);
FULL_MEM_BARRIER;
return res;
}
@@ -70,7 +70,12 @@
__ATOMIC_RELAXED, __ATOMIC_RELAXED);
return value;
} else {
- return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
+ T value = compare_value;
+ FULL_MEM_BARRIER;
+ __atomic_compare_exchange(dest, &value, &exchange_value, /*weak*/false,
+ __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+ FULL_MEM_BARRIER;
+ return value;
}
}
More information about the aarch64-port-dev
mailing list