8261579: AArch64: Support for weaker memory ordering in Atomic
Reviewed-by: adinn, shade
This commit is contained in:
parent
ee1e202bc3
commit
a97715755d
@ -45,5 +45,9 @@ extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_8_impl;
|
|||||||
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_1_relaxed_impl;
|
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_1_relaxed_impl;
|
||||||
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_4_relaxed_impl;
|
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_4_relaxed_impl;
|
||||||
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_8_relaxed_impl;
|
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_8_relaxed_impl;
|
||||||
|
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_4_release_impl;
|
||||||
|
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_8_release_impl;
|
||||||
|
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_4_seq_cst_impl;
|
||||||
|
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_8_seq_cst_impl;
|
||||||
|
|
||||||
#endif // CPU_AARCH64_ATOMIC_AARCH64_HPP
|
#endif // CPU_AARCH64_ATOMIC_AARCH64_HPP
|
||||||
|
@ -5956,6 +5956,10 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
acquire = false;
|
acquire = false;
|
||||||
release = false;
|
release = false;
|
||||||
break;
|
break;
|
||||||
|
case memory_order_release:
|
||||||
|
acquire = false;
|
||||||
|
release = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
acquire = true;
|
acquire = true;
|
||||||
release = true;
|
release = true;
|
||||||
@ -6037,6 +6041,20 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
(_masm, &aarch64_atomic_cmpxchg_8_relaxed_impl);
|
(_masm, &aarch64_atomic_cmpxchg_8_relaxed_impl);
|
||||||
gen_cas_entry(MacroAssembler::xword, memory_order_relaxed);
|
gen_cas_entry(MacroAssembler::xword, memory_order_relaxed);
|
||||||
|
|
||||||
|
AtomicStubMark mark_cmpxchg_4_release
|
||||||
|
(_masm, &aarch64_atomic_cmpxchg_4_release_impl);
|
||||||
|
gen_cas_entry(MacroAssembler::word, memory_order_release);
|
||||||
|
AtomicStubMark mark_cmpxchg_8_release
|
||||||
|
(_masm, &aarch64_atomic_cmpxchg_8_release_impl);
|
||||||
|
gen_cas_entry(MacroAssembler::xword, memory_order_release);
|
||||||
|
|
||||||
|
AtomicStubMark mark_cmpxchg_4_seq_cst
|
||||||
|
(_masm, &aarch64_atomic_cmpxchg_4_seq_cst_impl);
|
||||||
|
gen_cas_entry(MacroAssembler::word, memory_order_seq_cst);
|
||||||
|
AtomicStubMark mark_cmpxchg_8_seq_cst
|
||||||
|
(_masm, &aarch64_atomic_cmpxchg_8_seq_cst_impl);
|
||||||
|
gen_cas_entry(MacroAssembler::xword, memory_order_seq_cst);
|
||||||
|
|
||||||
ICache::invalidate_range(first_entry, __ pc() - first_entry);
|
ICache::invalidate_range(first_entry, __ pc() - first_entry);
|
||||||
}
|
}
|
||||||
#endif // LINUX
|
#endif // LINUX
|
||||||
@ -7203,6 +7221,10 @@ DEFAULT_ATOMIC_OP(cmpxchg, 8, )
|
|||||||
DEFAULT_ATOMIC_OP(cmpxchg, 1, _relaxed)
|
DEFAULT_ATOMIC_OP(cmpxchg, 1, _relaxed)
|
||||||
DEFAULT_ATOMIC_OP(cmpxchg, 4, _relaxed)
|
DEFAULT_ATOMIC_OP(cmpxchg, 4, _relaxed)
|
||||||
DEFAULT_ATOMIC_OP(cmpxchg, 8, _relaxed)
|
DEFAULT_ATOMIC_OP(cmpxchg, 8, _relaxed)
|
||||||
|
DEFAULT_ATOMIC_OP(cmpxchg, 4, _release)
|
||||||
|
DEFAULT_ATOMIC_OP(cmpxchg, 8, _release)
|
||||||
|
DEFAULT_ATOMIC_OP(cmpxchg, 4, _seq_cst)
|
||||||
|
DEFAULT_ATOMIC_OP(cmpxchg, 8, _seq_cst)
|
||||||
|
|
||||||
#undef DEFAULT_ATOMIC_OP
|
#undef DEFAULT_ATOMIC_OP
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
#ifndef OS_CPU_BSD_AARCH64_ATOMIC_BSD_AARCH64_HPP
|
#ifndef OS_CPU_BSD_AARCH64_ATOMIC_BSD_AARCH64_HPP
|
||||||
#define OS_CPU_BSD_AARCH64_ATOMIC_BSD_AARCH64_HPP
|
#define OS_CPU_BSD_AARCH64_ATOMIC_BSD_AARCH64_HPP
|
||||||
|
|
||||||
|
#include "utilities/debug.hpp"
|
||||||
|
|
||||||
// Implementation of class atomic
|
// Implementation of class atomic
|
||||||
// Note that memory_order_conservative requires a full barrier after atomic stores.
|
// Note that memory_order_conservative requires a full barrier after atomic stores.
|
||||||
// See https://patchwork.kernel.org/patch/3575821/
|
// See https://patchwork.kernel.org/patch/3575821/
|
||||||
@ -64,17 +66,40 @@ inline T Atomic::PlatformCmpxchg<byte_size>::operator()(T volatile* dest,
|
|||||||
T exchange_value,
|
T exchange_value,
|
||||||
atomic_memory_order order) const {
|
atomic_memory_order order) const {
|
||||||
STATIC_ASSERT(byte_size == sizeof(T));
|
STATIC_ASSERT(byte_size == sizeof(T));
|
||||||
if (order == memory_order_relaxed) {
|
if (order == memory_order_conservative) {
|
||||||
T value = compare_value;
|
T value = compare_value;
|
||||||
|
FULL_MEM_BARRIER;
|
||||||
__atomic_compare_exchange(dest, &value, &exchange_value, /*weak*/false,
|
__atomic_compare_exchange(dest, &value, &exchange_value, /*weak*/false,
|
||||||
__ATOMIC_RELAXED, __ATOMIC_RELAXED);
|
__ATOMIC_RELAXED, __ATOMIC_RELAXED);
|
||||||
|
FULL_MEM_BARRIER;
|
||||||
return value;
|
return value;
|
||||||
} else {
|
} else {
|
||||||
|
STATIC_ASSERT (
|
||||||
|
// The modes that align with C++11 are intended to
|
||||||
|
// follow the same semantics.
|
||||||
|
memory_order_relaxed == __ATOMIC_RELAXED &&
|
||||||
|
memory_order_acquire == __ATOMIC_ACQUIRE &&
|
||||||
|
memory_order_release == __ATOMIC_RELEASE &&
|
||||||
|
memory_order_acq_rel == __ATOMIC_ACQ_REL &&
|
||||||
|
memory_order_seq_cst == __ATOMIC_SEQ_CST);
|
||||||
|
|
||||||
|
// Some sanity checking on the memory order. It makes no
|
||||||
|
// sense to have a release operation for a store that never
|
||||||
|
// happens.
|
||||||
|
int failure_memory_order;
|
||||||
|
switch (order) {
|
||||||
|
case memory_order_release:
|
||||||
|
failure_memory_order = memory_order_relaxed; break;
|
||||||
|
case memory_order_acq_rel:
|
||||||
|
failure_memory_order = memory_order_acquire; break;
|
||||||
|
default:
|
||||||
|
failure_memory_order = order;
|
||||||
|
}
|
||||||
|
assert(failure_memory_order <= order, "must be");
|
||||||
|
|
||||||
T value = compare_value;
|
T value = compare_value;
|
||||||
FULL_MEM_BARRIER;
|
|
||||||
__atomic_compare_exchange(dest, &value, &exchange_value, /*weak*/false,
|
__atomic_compare_exchange(dest, &value, &exchange_value, /*weak*/false,
|
||||||
__ATOMIC_RELAXED, __ATOMIC_RELAXED);
|
order, failure_memory_order);
|
||||||
FULL_MEM_BARRIER;
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,55 @@ aarch64_atomic_cmpxchg_8_default_impl:
|
|||||||
dmb ish
|
dmb ish
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.globl aarch64_atomic_cmpxchg_1_relaxed_default_impl
|
.globl aarch64_atomic_cmpxchg_4_release_default_impl
|
||||||
|
.align 5
|
||||||
|
aarch64_atomic_cmpxchg_4_release_default_impl:
|
||||||
|
prfm pstl1strm, [x0]
|
||||||
|
0: ldxr w3, [x0]
|
||||||
|
cmp w3, w1
|
||||||
|
b.ne 1f
|
||||||
|
stlxr w8, w2, [x0]
|
||||||
|
cbnz w8, 0b
|
||||||
|
1: mov w0, w3
|
||||||
|
ret
|
||||||
|
|
||||||
|
.globl aarch64_atomic_cmpxchg_8_release_default_impl
|
||||||
|
.align 5
|
||||||
|
aarch64_atomic_cmpxchg_8_release_default_impl:
|
||||||
|
prfm pstl1strm, [x0]
|
||||||
|
0: ldxr x3, [x0]
|
||||||
|
cmp x3, x1
|
||||||
|
b.ne 1f
|
||||||
|
stlxr w8, x2, [x0]
|
||||||
|
cbnz w8, 0b
|
||||||
|
1: mov x0, x3
|
||||||
|
ret
|
||||||
|
|
||||||
|
.globl aarch64_atomic_cmpxchg_4_seq_cst_default_impl
|
||||||
|
.align 5
|
||||||
|
aarch64_atomic_cmpxchg_4_seq_cst_default_impl:
|
||||||
|
prfm pstl1strm, [x0]
|
||||||
|
0: ldaxr w3, [x0]
|
||||||
|
cmp w3, w1
|
||||||
|
b.ne 1f
|
||||||
|
stlxr w8, w2, [x0]
|
||||||
|
cbnz w8, 0b
|
||||||
|
1: mov w0, w3
|
||||||
|
ret
|
||||||
|
|
||||||
|
.globl aarch64_atomic_cmpxchg_8_seq_cst_default_impl
|
||||||
|
.align 5
|
||||||
|
aarch64_atomic_cmpxchg_8_seq_cst_default_impl:
|
||||||
|
prfm pstl1strm, [x0]
|
||||||
|
0: ldaxr x3, [x0]
|
||||||
|
cmp x3, x1
|
||||||
|
b.ne 1f
|
||||||
|
stlxr w8, x2, [x0]
|
||||||
|
cbnz w8, 0b
|
||||||
|
1: mov x0, x3
|
||||||
|
ret
|
||||||
|
|
||||||
|
.globl aarch64_atomic_cmpxchg_1_relaxed_default_impl
|
||||||
.align 5
|
.align 5
|
||||||
aarch64_atomic_cmpxchg_1_relaxed_default_impl:
|
aarch64_atomic_cmpxchg_1_relaxed_default_impl:
|
||||||
prfm pstl1strm, [x0]
|
prfm pstl1strm, [x0]
|
||||||
|
@ -151,6 +151,11 @@ inline T Atomic::PlatformCmpxchg<4>::operator()(T volatile* dest,
|
|||||||
switch (order) {
|
switch (order) {
|
||||||
case memory_order_relaxed:
|
case memory_order_relaxed:
|
||||||
stub = aarch64_atomic_cmpxchg_4_relaxed_impl; break;
|
stub = aarch64_atomic_cmpxchg_4_relaxed_impl; break;
|
||||||
|
case memory_order_release:
|
||||||
|
stub = aarch64_atomic_cmpxchg_4_release_impl; break;
|
||||||
|
case memory_order_acq_rel:
|
||||||
|
case memory_order_seq_cst:
|
||||||
|
stub = aarch64_atomic_cmpxchg_4_seq_cst_impl; break;
|
||||||
default:
|
default:
|
||||||
stub = aarch64_atomic_cmpxchg_4_impl; break;
|
stub = aarch64_atomic_cmpxchg_4_impl; break;
|
||||||
}
|
}
|
||||||
@ -169,6 +174,11 @@ inline T Atomic::PlatformCmpxchg<8>::operator()(T volatile* dest,
|
|||||||
switch (order) {
|
switch (order) {
|
||||||
case memory_order_relaxed:
|
case memory_order_relaxed:
|
||||||
stub = aarch64_atomic_cmpxchg_8_relaxed_impl; break;
|
stub = aarch64_atomic_cmpxchg_8_relaxed_impl; break;
|
||||||
|
case memory_order_release:
|
||||||
|
stub = aarch64_atomic_cmpxchg_8_release_impl; break;
|
||||||
|
case memory_order_acq_rel:
|
||||||
|
case memory_order_seq_cst:
|
||||||
|
stub = aarch64_atomic_cmpxchg_8_seq_cst_impl; break;
|
||||||
default:
|
default:
|
||||||
stub = aarch64_atomic_cmpxchg_8_impl; break;
|
stub = aarch64_atomic_cmpxchg_8_impl; break;
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ enum atomic_memory_order {
|
|||||||
memory_order_acquire = 2,
|
memory_order_acquire = 2,
|
||||||
memory_order_release = 3,
|
memory_order_release = 3,
|
||||||
memory_order_acq_rel = 4,
|
memory_order_acq_rel = 4,
|
||||||
|
memory_order_seq_cst = 5,
|
||||||
// Strong two-way memory barrier.
|
// Strong two-way memory barrier.
|
||||||
memory_order_conservative = 8
|
memory_order_conservative = 8
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user