[aarch64-port-dev ] RFR: aarch64: minor improvements of atomic operations
Yangfei (Felix)
felix.yang at huawei.com
Wed Nov 13 09:46:55 UTC 2019
> -----Original Message-----
> From: Andrew Haley [mailto:aph at redhat.com]
> Sent: Wednesday, November 13, 2019 5:39 PM
> To: Yangfei (Felix) <felix.yang at huawei.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
>
> On 11/13/19 9:26 AM, Yangfei (Felix) wrote:
> > Yes, the cmpxchg case is different here.
> > So the v2 patch in my previous mail approved?
> > Will create a bug and do necessary testing.
>
> I don't know which patch is v2, but for the reasons carefully laid out in the
> kernel-dev thread we don't need two full barriers. The first version of
> Atomic::PlatformCmpxchg you posted is OK.
>
Well, I think the cmpxchg case is different: the compare in the loop may fail and then we don't got a change to execute the stlxr instruction.
This is explicitedly discussed in that thread: https://patchwork.kernel.org/patch/3575821/
As a result, aarch64 Linux plants two barriers in that patch:
@@ -112,17 +114,20 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
unsigned long tmp;
int oldval;
+ smp_mb(); < ========
+
asm volatile("// atomic_cmpxchg\n"
-"1: ldaxr %w1, %2\n"
+"1: ldxr %w1, %2\n"
" cmp %w1, %w3\n"
" b.ne 2f\n"
-" stlxr %w0, %w4, %2\n"
+" stxr %w0, %w4, %2\n"
" cbnz %w0, 1b\n"
"2:"
: "=&r" (tmp), "=&r" (oldval), "+Q" (ptr->counter)
: "Ir" (old), "r" (new)
: "cc", "memory");
+ smp_mb(); < ========
return oldval;
}
That's why I switched to the 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